diff --git a/base/applications/rapps/lang/zh-CN.rc b/base/applications/rapps/lang/zh-CN.rc index 6b12fe62671..57143c9dc3a 100644 --- a/base/applications/rapps/lang/zh-CN.rc +++ b/base/applications/rapps/lang/zh-CN.rc @@ -22,7 +22,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "刷新(&R)", ID_REFRESH MENUITEM SEPARATOR - MENUITEM "Update Da&tabase", ID_RESETDB + MENUITEM "更新数据库(&A)", ID_RESETDB END POPUP "帮助" BEGIN @@ -52,7 +52,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "刷新(&R)", ID_REFRESH MENUITEM SEPARATOR - MENUITEM "Update Da&tabase", ID_RESETDB + MENUITEM "更新数据库(&A)", ID_RESETDB END END diff --git a/base/applications/rapps/lang/zh-TW.rc b/base/applications/rapps/lang/zh-TW.rc new file mode 100644 index 00000000000..a7e5ac0f7f5 --- /dev/null +++ b/base/applications/rapps/lang/zh-TW.rc @@ -0,0 +1,202 @@ +/* + * Translated by Song Fuchang (0xfc) + * Converted by OpenCC 0.4.2 + */ + +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL + +IDR_MAINMENU MENU +BEGIN + POPUP "檔案(&F)" + BEGIN + MENUITEM "設定(&S)", ID_SETTINGS + MENUITEM SEPARATOR + MENUITEM "退出(&X)", ID_EXIT + END + POPUP "程式(&P)" + BEGIN + MENUITEM "安裝(&I)", ID_INSTALL + MENUITEM "解除安裝(&U)", ID_UNINSTALL + MENUITEM "修改(&M)", ID_MODIFY + MENUITEM SEPARATOR + MENUITEM "從登錄檔刪除(&E)", ID_REGREMOVE + MENUITEM SEPARATOR + MENUITEM "重新整理(&R)", ID_REFRESH + MENUITEM SEPARATOR + MENUITEM "更新資料庫(&A)", ID_RESETDB + END + POPUP "幫助" + BEGIN + MENUITEM "幫助內容", ID_HELP, GRAYED + MENUITEM "關於", ID_ABOUT + END +END + +IDR_LINKMENU MENU +BEGIN + POPUP "popup" + BEGIN + MENUITEM "在瀏覽器中開啟連結(&O)", ID_OPEN_LINK + MENUITEM "複製連結到剪貼簿(&C)", ID_COPY_LINK + END +END + +IDR_APPLICATIONMENU MENU +BEGIN + POPUP "popup" + BEGIN + MENUITEM "安裝(&I)", ID_INSTALL + MENUITEM "解除安裝(&U)", ID_UNINSTALL + MENUITEM "修改(&M)", ID_MODIFY + MENUITEM SEPARATOR + MENUITEM "從登錄檔刪除(&E)", ID_REGREMOVE + MENUITEM SEPARATOR + MENUITEM "重新整理(&R)", ID_REFRESH + MENUITEM SEPARATOR + MENUITEM "更新資料庫(&A)", ID_RESETDB + END +END + +IDD_SETTINGS_DIALOG DIALOGEX DISCARDABLE 0, 0, 250, 144 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "設定" +FONT 8, "MS Shell Dlg" +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 + + 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 + PUSHBUTTON "選擇(&C)", IDC_CHOOSE, 187, 85, 50, 14 + AUTOCHECKBOX "在安裝完程式後刪除安裝程式(&D)", IDC_DEL_AFTER_INSTALL, 16, 100, 218, 12 + + PUSHBUTTON "預設", IDC_DEFAULT_SETTINGS, 8, 124, 60, 14 + PUSHBUTTON "確定", IDOK, 116, 124, 60, 14 + PUSHBUTTON "取消", IDCANCEL, 181, 124, 60, 14 +END + +IDD_INSTALL_DIALOG DIALOGEX DISCARDABLE 0, 0, 216, 97 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "安裝程式" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "...", IDC_INSTALL_TEXT, 4, 5, 209, 35 + + AUTORADIOBUTTON "從存儲裝置安裝 (CD 或 DVD)(&I)", IDC_CD_INSTALL, 10, 46, 197, 11, WS_GROUP + AUTORADIOBUTTON "下載並安裝(&D)", IDC_DOWNLOAD_INSTALL, 10, 59, 197, 11, NOT WS_TABSTOP + + PUSHBUTTON "確定", IDOK, 86, 78, 60, 14 + PUSHBUTTON "取消", IDCANCEL, 150, 78, 60, 14 +END + +IDD_DOWNLOAD_DIALOG DIALOGEX LOADONCALL MOVEABLE DISCARDABLE 0, 0, 220, 76 +STYLE DS_SHELLFONT | DS_CENTER | WS_BORDER | WS_CAPTION | WS_POPUP | WS_SYSMENU | WS_VISIBLE +CAPTION "正在下載..." +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Progress1", IDC_DOWNLOAD_PROGRESS, "msctls_progress32", WS_BORDER | PBS_SMOOTH, 10, 10, 200, 12 + LTEXT "", IDC_DOWNLOAD_STATUS, 10, 30, 200, 10, SS_CENTER + PUSHBUTTON "取消", IDCANCEL, 85, 58, 50, 15, WS_GROUP | WS_TABSTOP +END + +IDD_ABOUT_DIALOG DIALOGEX 22, 16, 190, 66 +STYLE DS_SHELLFONT | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME +CAPTION "關於" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "ReactOS 程式管理器 版權所有 (C) 2009\n作者 Dmitry Chapyshev (dmitry@reactos.org)", IDC_STATIC, 48, 7, 130, 39 + PUSHBUTTON "關閉", IDOK, 133, 46, 50, 14 + ICON IDI_MAIN, IDC_STATIC, 10, 10, 7, 30 +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_TOOLTIP_INSTALL "安裝" + IDS_TOOLTIP_UNINSTALL "解除安裝" + IDS_TOOLTIP_MODIFY "修改" + IDS_TOOLTIP_SETTINGS "設定" + IDS_TOOLTIP_REFRESH "重新整理" + IDS_TOOLTIP_EXIT "退出" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APP_NAME "名稱" + IDS_APP_INST_VERSION "版本" + IDS_APP_DESCRIPTION "描述" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_INFO_VERSION "版本:" + IDS_INFO_DESCRIPTION "描述:" + IDS_INFO_PUBLISHER "\n釋出者:" + IDS_INFO_HELPLINK "\n幫助連結:" + IDS_INFO_HELPPHONE "\n幫助電話:" + IDS_INFO_README "\n必讀:" + IDS_INFO_REGOWNER "\n註冊所有者:" + IDS_INFO_PRODUCTID "\n產品 ID:" + IDS_INFO_CONTACT "\n聯繫方式:" + IDS_INFO_UPDATEINFO "\n更新資訊:" + IDS_INFO_INFOABOUT "\n關於資訊:" + IDS_INFO_COMMENTS "\n註釋:" + IDS_INFO_INSTLOCATION "\n安裝位置:" + IDS_INFO_INSTALLSRC "\n安裝源:" + IDS_INFO_UNINSTALLSTR "\n解除安裝字元串:" + IDS_INFO_MODIFYPATH "\n修改路徑:" + IDS_INFO_INSTALLDATE "\n安裝日期:" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_AINFO_VERSION "\n版本:" + IDS_AINFO_DESCRIPTION "\n描述:" + IDS_AINFO_SIZE "\n大小:" + IDS_AINFO_URLSITE "\n主頁:" + IDS_AINFO_LICENCE "\n協議:" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_CAT_AUDIO "音訊" + IDS_CAT_DEVEL "開發" + IDS_CAT_DRIVERS "驅動程式" + IDS_CAT_EDU "教育與娛樂" + IDS_CAT_ENGINEER "工程" + IDS_CAT_FINANCE "經濟" + IDS_CAT_GAMES "遊戲與娛樂" + IDS_CAT_GRAPHICS "圖形" + IDS_CAT_INTERNET "Internet 與網路" + IDS_CAT_LIBS "庫" + IDS_CAT_OFFICE "辦公" + IDS_CAT_OTHER "其他" + IDS_CAT_SCIENCE "科學" + IDS_CAT_TOOLS "工具" + IDS_CAT_VIDEO "視訊" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APPTITLE "ReactOS 程式管理器" + IDS_SEARCH_TEXT "搜索..." + IDS_INSTALL "安裝" + IDS_UNINSTALL "解除安裝" + IDS_MODIFY "修改" + IDS_APPS_COUNT "程式個數:%d" + IDS_WELCOME_TITLE "歡迎來到 ReactOS 程式管理器!\n\n" + IDS_WELCOME_TEXT "從左欄選擇一個類別,然後選擇要安裝或解除安裝的程式。\nReactOS 網站:" + IDS_WELCOME_URL "http://www.reactos.org" + IDS_INSTALLED "已安裝" + IDS_AVAILABLEFORINST "可安裝" + IDS_UPDATES "更新" + IDS_APPLICATIONS "應用程式" + IDS_CHOOSE_FOLDER_TEXT "請選擇用來儲存下載檔案的資料夾:" + IDS_CHOOSE_FOLDER_ERROR "您選擇的資料夾不存在。創建嗎?" + IDS_USER_NOT_ADMIN "您必須以管理員許可權啟動 ""ReactOS 程式管理器""!" + IDS_APP_REG_REMOVE "您確定要從登錄檔刪除該程式的資料嗎?" + IDS_INFORMATION "資訊" + IDS_UNABLE_TO_REMOVE "無法從登錄檔刪除該程式的資料!" +END diff --git a/base/applications/rapps/rapps/mpc.txt b/base/applications/rapps/rapps/mpc.txt index ee7be799fdf..155f141f9d7 100644 --- a/base/applications/rapps/rapps/mpc.txt +++ b/base/applications/rapps/rapps/mpc.txt @@ -7,7 +7,7 @@ Licence = GPL Description = A media player. Size = 7.08MB Category = 1 -URLSite = http://mpc-hc.sourceforge.net/ +URLSite = http://mpc-hc.org/ URLDownload = http://garr.dl.sourceforge.net/project/mpc-hc/MPC%20HomeCinema%20-%20Win32/MPC-HC_v1.6.8_x86/MPC-HC.1.6.8.x86.exe CDPath = none diff --git a/base/applications/rapps/rsrc.rc b/base/applications/rapps/rsrc.rc index e28ae42a0fd..da610c3cd60 100644 --- a/base/applications/rapps/rsrc.rc +++ b/base/applications/rapps/rsrc.rc @@ -56,3 +56,6 @@ #ifdef LANGUAGE_ZH_CN #include "lang/zh-CN.rc" #endif +#ifdef LANGUAGE_ZH_TW + #include "lang/zh-TW.rc" +#endif diff --git a/boot/bootdata/hivesys.inf b/boot/bootdata/hivesys.inf index b027a70a8ce..5c5f94e0b4e 100644 --- a/boot/bootdata/hivesys.inf +++ b/boot/bootdata/hivesys.inf @@ -1149,6 +1149,8 @@ HKLM,"SYSTEM\CurrentControlSet\Control\SecurityProviders\SaslProfiles",,0x000000 ; Service groups HKLM,"SYSTEM\CurrentControlSet\Control\ServiceGroupOrder","List",0x00010000, \ + "System Reserved", \ + "EMS", \ "Boot Bus Extender", \ "System Bus Extender", \ "SCSI Miniport", \ @@ -1342,6 +1344,13 @@ HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Start",0x00010001,0x00000002 HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Type",0x00010001,0x00000020 HKLM,"SYSTEM\CurrentControlSet\Services\DHCP\Parameters","ServiceDll",0x00020000,"%SystemRoot%\system32\dhcpcsvc.dll" +; EMS Serial Administration Console Driver +HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Group",0x00000000,"EMS" +HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","ImagePath",0x00020000,"system32\drivers\sacdrv.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Start",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Type",0x00010001,0x00000001 + ; Event logging service HKLM,"SYSTEM\CurrentControlSet\Services\EventLog",,0x00000010 HKLM,"SYSTEM\CurrentControlSet\Services\EventLog","DisplayName",0x00000000,"Event Logger" diff --git a/boot/bootdata/txtsetup.sif b/boot/bootdata/txtsetup.sif index b34c51ef883..d2675d94f39 100644 --- a/boot/bootdata/txtsetup.sif +++ b/boot/bootdata/txtsetup.sif @@ -18,6 +18,7 @@ FreeSysPartDiskSpace=350 [SourceDisksFiles] acpi.sys=,,,,,,,,,,,,4 nmidebug.sys=,,,,,,x,,,,,,4 +sacdrv.sys=,,,,,,x,,,,,,4 uniata.sys=,,,,,,x,,,,,,4 buslogic.sys=,,,,,,x,,,,,,4 blue.sys=,,,,,,x,,,,,,4 diff --git a/cmake/Platform/Windows-cl.cmake b/cmake/Platform/Windows-cl.cmake deleted file mode 100644 index afd36b8542d..00000000000 --- a/cmake/Platform/Windows-cl.cmake +++ /dev/null @@ -1,307 +0,0 @@ -# try to load any previously computed information for C on this platform -INCLUDE( ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake OPTIONAL) -# try to load any previously computed information for CXX on this platform -INCLUDE( ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake OPTIONAL) - -SET(WIN32 1) - -INCLUDE(Platform/cl) - -############ -# Detect WDK build environment -IF($ENV{DDKBUILDENV} MATCHES "chk") - MESSAGE(STATUS "DDK/WDK checked build environment detected.") - SET(CMAKE_USE_WDK_ENV 1) -ENDIF() - -IF($ENV{DDKBUILDENV} MATCHES "fre") - MESSAGE(STATUS "DDK/WDK free build environment detected.") - SET(CMAKE_USE_WDK_ENV 1) -ENDIF() - -if(CMAKE_USE_WDK_ENV) - - # Detect output architecture - if(NOT ARCH) - if($ENV{AMD64} MATCHES 1) - set(ARCH amd64) - set(MSVC_C_ARCHITECTURE_ID 64) - else() - set(ARCH i386) - endif() - endif() - - # Force C/C++ Compilers - include(CMakeForceCompiler) - CMAKE_FORCE_C_COMPILER(cl MSVC) - CMAKE_FORCE_CXX_COMPILER(cl MSVC) - - # Add library directories - STRING(REPLACE * ${ARCH} ATL_LIB_PATH $ENV{ATL_LIB_PATH}) - STRING(REPLACE * ${ARCH} CRT_LIB_PATH $ENV{CRT_LIB_PATH}) - STRING(REPLACE * ${ARCH} DDK_LIB_PATH $ENV{DDK_LIB_PATH}) - STRING(REPLACE * ${ARCH} KMDF_LIB_PATH $ENV{KMDF_LIB_PATH}) - STRING(REPLACE * ${ARCH} MFC_LIB_PATH $ENV{MFC_LIB_PATH}) - STRING(REPLACE * ${ARCH} SDK_LIB_PATH $ENV{SDK_LIB_PATH}) - LINK_DIRECTORIES(${ATL_LIB_PATH} - ${CRT_LIB_PATH} - ${DDK_LIB_PATH} - ${IFSKIT_LIB_PATH} - ${KMDF_LIB_PATH} - ${MFC_LIB_PATH} - ${SDK_LIB_PATH}) - - # Add environment variables - if(NOT CMAKE_CROSSCOMPILING) - set(ENV{INCLUDE} "$ENV{CRT_INC_PATH};$ENV{SDK_INC_PATH};$ENV{SDK_INC_PATH}\\crt\\stl60") - include_directories($ENV{INCLUDE}) - set(ENV{LIBPATH} "${CRT_LIB_PATH};${SDK_LIB_PATH}") - set(ENV{USE_MSVCRT} 1) - set(ENV{USE_STL} 1) - set(ENV{STL_VER} 60) - endif() -endif() - -############ - -# Set lib path for ARM compiler -if(${ARCH} MATCHES arm) - message("Using ARM build for cross compilation. Host tools are x86.") - - # Force C/C++ Compilers - include(CMakeForceCompiler) - CMAKE_FORCE_C_COMPILER(cl MSVC) - CMAKE_FORCE_CXX_COMPILER(cl MSVC) - - if(NOT CMAKE_CROSSCOMPILING) - message("Using x86 target for ARM host tools.") - set(ARCH i386) - - LINK_DIRECTORIES($ENV{WindowsSdkDir}\\Lib\\win8\\um\\x86) - endif() - - #LINK_DIRECTORIES($ENV{LIB}) -endif() - - -############ - -SET(CMAKE_CREATE_WIN32_EXE /subsystem:windows) -SET(CMAKE_CREATE_CONSOLE_EXE /subsystem:console) - -IF(CMAKE_GENERATOR MATCHES "Visual Studio 6") - SET (CMAKE_NO_BUILD_TYPE 1) -ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 6") -IF(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio") - SET (CMAKE_NO_BUILD_TYPE 1) - SET (CMAKE_CONFIGURATION_TYPES "Debug;Release;MinSizeRel;RelWithDebInfo" CACHE STRING - "Semicolon separated list of supported configuration types, only supports Debug, Release, MinSizeRel, and RelWithDebInfo, anything else will be ignored.") - MARK_AS_ADVANCED(CMAKE_CONFIGURATION_TYPES) -ENDIF(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio") -# does the compiler support pdbtype and is it the newer compiler -IF(CMAKE_GENERATOR MATCHES "Visual Studio 8") - SET(CMAKE_COMPILER_2005 1) -ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8") - -# make sure to enable languages after setting configuration types -ENABLE_LANGUAGE(RC) -SET(CMAKE_COMPILE_RESOURCE "rc /fo ") - -# for nmake we need to compute some information about the compiler -# that is being used. -# the compiler may be free command line, 6, 7, or 71, and -# each have properties that must be determined. -# to avoid running these tests with each cmake run, the -# test results are saved in CMakeCPlatform.cmake, a file -# that is automatically copied into try_compile directories -# by the global generator. -SET(MSVC_IDE 1) -IF(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja") - SET(MSVC_IDE 0) - IF(NOT CMAKE_VC_COMPILER_TESTS_RUN) - SET(CMAKE_VC_COMPILER_TESTS 1) - SET(testNmakeCLVersionFile - "${CMAKE_ROOT}/Modules/CMakeTestNMakeCLVersion.c") - STRING(REGEX REPLACE "/" "\\\\" testNmakeCLVersionFile "${testNmakeCLVersionFile}") - MESSAGE(STATUS "Check for CL compiler version") - SET(CMAKE_TEST_COMPILER ${CMAKE_C_COMPILER}) - IF (NOT CMAKE_C_COMPILER) - SET(CMAKE_TEST_COMPILER ${CMAKE_CXX_COMPILER}) - ENDIF(NOT CMAKE_C_COMPILER) - EXEC_PROGRAM(${CMAKE_TEST_COMPILER} - ARGS /nologo -EP \"${testNmakeCLVersionFile}\" - OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT - RETURN_VALUE CMAKE_COMPILER_RETURN - ) - IF(NOT CMAKE_COMPILER_RETURN) - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining the version of compiler passed with the following output:\n" - "${CMAKE_COMPILER_OUTPUT}\n\n") - STRING(REGEX REPLACE "\n" " " compilerVersion "${CMAKE_COMPILER_OUTPUT}") - STRING(REGEX REPLACE ".*VERSION=(.*)" "\\1" - compilerVersion "${compilerVersion}") - MESSAGE(STATUS "Check for CL compiler version - ${compilerVersion}") - SET(MSVC60) - SET(MSVC70) - SET(MSVC71) - SET(MSVC80) - SET(CMAKE_COMPILER_2005) - IF("${compilerVersion}" LESS 1300) - SET(MSVC60 1) - SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 1) - ENDIF("${compilerVersion}" LESS 1300) - IF("${compilerVersion}" EQUAL 1300) - SET(MSVC70 1) - SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 0) - ENDIF("${compilerVersion}" EQUAL 1300) - IF("${compilerVersion}" EQUAL 1310) - SET(MSVC71 1) - SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 0) - ENDIF("${compilerVersion}" EQUAL 1310) - IF("${compilerVersion}" EQUAL 1400) - SET(MSVC80 1) - SET(CMAKE_COMPILER_2005 1) - ENDIF("${compilerVersion}" EQUAL 1400) - IF("${compilerVersion}" EQUAL 1500) - SET(MSVC90 1) - ENDIF("${compilerVersion}" EQUAL 1500) - IF("${compilerVersion}" EQUAL 1600) - SET(MSVC10 1) - ENDIF("${compilerVersion}" EQUAL 1600) - SET(MSVC_VERSION "${compilerVersion}") - ELSE(NOT CMAKE_COMPILER_RETURN) - MESSAGE(STATUS "Check for CL compiler version - failed") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining the version of compiler failed with the following output:\n" - "${CMAKE_COMPILER_OUTPUT}\n\n") - ENDIF(NOT CMAKE_COMPILER_RETURN) - # try to figure out if we are running the free command line - # tools from Microsoft. These tools do not provide debug libraries, - # so the link flags used have to be different. - MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp2") - SET(testForFreeVCFile - "${CMAKE_ROOT}/Modules/CMakeTestForFreeVC.cxx") - STRING(REGEX REPLACE "/" "\\\\" testForFreeVCFile "${testForFreeVCFile}") - MESSAGE(STATUS "Check if this is a free VC compiler") - EXEC_PROGRAM(${CMAKE_TEST_COMPILER} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp2 - ARGS /nologo /EHsc - \"${testForFreeVCFile}\" - OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT - RETURN_VALUE CMAKE_COMPILER_RETURN - ) - IF(CMAKE_COMPILER_RETURN) - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if this is a free VC compiler failed with the following output:\n" - "${CMAKE_COMPILER_OUTPUT}\n\n") - MESSAGE(STATUS "Check if this is a free VC compiler - yes") - SET(CMAKE_USING_VC_FREE_TOOLS 1) - ELSE(CMAKE_COMPILER_RETURN) - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if this is a free VC compiler passed with the following output:\n" - "${CMAKE_COMPILER_OUTPUT}\n\n") - MESSAGE(STATUS "Check if this is a free VC compiler - no") - SET(CMAKE_USING_VC_FREE_TOOLS 0) - ENDIF(CMAKE_COMPILER_RETURN) - MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp3") - ENDIF(NOT CMAKE_VC_COMPILER_TESTS_RUN) -ENDIF(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja") - -IF(MSVC_C_ARCHITECTURE_ID MATCHES 64) - SET(CMAKE_CL_64 1) -ELSE(MSVC_C_ARCHITECTURE_ID MATCHES 64) - SET(CMAKE_CL_64 0) -ENDIF(MSVC_C_ARCHITECTURE_ID MATCHES 64) -IF(CMAKE_FORCE_WIN64 OR CMAKE_FORCE_IA64) - SET(CMAKE_CL_64 1) -ENDIF(CMAKE_FORCE_WIN64 OR CMAKE_FORCE_IA64) - -IF("${MSVC_VERSION}" GREATER 1599) - SET(MSVC_INCREMENTAL_DEFAULT ON) -ENDIF() - -# No support for old versions -if(MSVC_VERSION LESS 1310) -message(FATAL_ERROR "Your compiler is too old. Get a newer version!") -endif() - -# for 2005 make sure the manifest is put in the dll with mt -#SET(CMAKE_CXX_CREATE_SHARED_LIBRARY " -E vs_link_dll ${CMAKE_CXX_CREATE_SHARED_LIBRARY}") -#SET(CMAKE_CXX_CREATE_SHARED_MODULE " -E vs_link_dll ${CMAKE_CXX_CREATE_SHARED_MODULE}") -# create a C shared library -#SET(CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}") -# create a C shared module just copy the shared library rule -#SET(CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE}") -#SET(CMAKE_CXX_LINK_EXECUTABLE " -E vs_link_exe ${CMAKE_CXX_LINK_EXECUTABLE}") -#SET(CMAKE_C_LINK_EXECUTABLE " -E vs_link_exe ${CMAKE_C_LINK_EXECUTABLE}") - -SET(CMAKE_BUILD_TYPE_INIT Debug) -SET(CMAKE_CXX_FLAGS_DEBUG_INIT "") -SET(CMAKE_C_FLAGS_DEBUG_INIT "") -SET(CMAKE_CXX_FLAGS_INIT "") -SET(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/O1 /Ob1 /D NDEBUG") -SET(CMAKE_CXX_FLAGS_RELEASE_INIT "") -SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/Zi /O2 /Ob1") -SET(CMAKE_C_FLAGS_INIT "") -SET(CMAKE_C_FLAGS_MINSIZEREL_INIT "/O1 /Ob1 /D NDEBUG") -SET(CMAKE_C_FLAGS_RELEASE_INIT "") -SET(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/Zi /O2 /Ob1") -SET(CMAKE_C_STANDARD_LIBRARIES_INIT "") -SET(CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT}") -SET(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}") - -# executable linker flags -SET (CMAKE_LINK_DEF_FILE_FLAG "/DEF:") -# set the stack size and the machine type -SET(_MACHINE_ARCH_FLAG ${MSVC_C_ARCHITECTURE_ID}) -IF(NOT _MACHINE_ARCH_FLAG) - SET(_MACHINE_ARCH_FLAG ${MSVC_CXX_ARCHITECTURE_ID}) -ENDIF(NOT _MACHINE_ARCH_FLAG) -# HACK -if(${ARCH} MATCHES arm) - SET(_MACHINE_ARCH_FLAG ARM) -endif() -SET (CMAKE_EXE_LINKER_FLAGS_INIT - "${CMAKE_EXE_LINKER_FLAGS_INIT} /STACK:10000000 /machine:${_MACHINE_ARCH_FLAG}") - -# add /debug and /INCREMENTAL:YES to DEBUG and RELWITHDEBINFO also add pdbtype -# on versions that support it -SET( MSVC_INCREMENTAL_YES_FLAG "") -IF(NOT MSVC_INCREMENTAL_DEFAULT) - SET( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:YES") -ENDIF() - -IF (CMAKE_COMPILER_SUPPORTS_PDBTYPE) - SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug /pdbtype:sept ${MSVC_INCREMENTAL_YES_FLAG}") - SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug /pdbtype:sept ${MSVC_INCREMENTAL_YES_FLAG}") -ELSE (CMAKE_COMPILER_SUPPORTS_PDBTYPE) - SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug ${MSVC_INCREMENTAL_YES_FLAG}") - SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug ${MSVC_INCREMENTAL_YES_FLAG}") -ENDIF (CMAKE_COMPILER_SUPPORTS_PDBTYPE) -# for release and minsize release default to no incremental linking -SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT "/INCREMENTAL:NO") -SET(CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT "/INCREMENTAL:NO") - -# copy the EXE_LINKER flags to SHARED and MODULE linker flags -# shared linker flags -SET (CMAKE_SHARED_LINKER_FLAGS_INIT ${CMAKE_EXE_LINKER_FLAGS_INIT}) -SET (CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT}) -SET (CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT}) -SET (CMAKE_SHARED_LINKER_FLAGS_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT}) -SET (CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT}) -# module linker flags -SET (CMAKE_MODULE_LINKER_FLAGS_INIT ${CMAKE_SHARED_LINKER_FLAGS_INIT}) -SET (CMAKE_MODULE_LINKER_FLAGS_DEBUG_INIT ${CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT}) -SET (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT}) -SET (CMAKE_MODULE_LINKER_FLAGS_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT}) -SET (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT}) - -# save computed information for this platform -IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake") - CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCPlatform.cmake IMMEDIATE) -ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake") - -IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake") - CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXPlatform.cmake IMMEDIATE) -ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake") diff --git a/dll/win32/kernel32/CMakeLists.txt b/dll/win32/kernel32/CMakeLists.txt index caf39abae86..fc2cd0a6a2b 100644 --- a/dll/win32/kernel32/CMakeLists.txt +++ b/dll/win32/kernel32/CMakeLists.txt @@ -47,6 +47,7 @@ list(APPEND SOURCE client/file/delete.c client/file/deviceio.c client/file/dir.c + client/file/disk.c client/file/fileinfo.c client/file/filemap.c client/file/filename.c @@ -57,6 +58,7 @@ list(APPEND SOURCE client/file/lock.c client/file/mailslot.c client/file/move.c + client/file/mntpoint.c client/file/npipe.c client/file/rw.c client/file/tape.c diff --git a/dll/win32/kernel32/client/file/disk.c b/dll/win32/kernel32/client/file/disk.c new file mode 100644 index 00000000000..c54ebe97e67 --- /dev/null +++ b/dll/win32/kernel32/client/file/disk.c @@ -0,0 +1,424 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/kernel32/file/disk.c + * PURPOSE: Disk and Drive functions + * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) + * Erik Bos, Alexandre Julliard : + * GetLogicalDriveStringsA, + * GetLogicalDriveStringsW, GetLogicalDrives + * UPDATE HISTORY: + * Created 01/11/98 + */ +//WINE copyright notice: +/* + * DOS drives handling functions + * + * Copyright 1993 Erik Bos + * Copyright 1996 Alexandre Julliard + */ + +#include +#define NDEBUG +#include +DEBUG_CHANNEL(kernel32file); + +#define MAX_DOS_DRIVES 26 +HANDLE WINAPI InternalOpenDirW(IN LPCWSTR DirName, IN BOOLEAN Write); + +/* + * @implemented + */ +/* Synced to Wine-2008/12/28 */ +DWORD +WINAPI +GetLogicalDriveStringsA(IN DWORD nBufferLength, + IN LPSTR lpBuffer) +{ + DWORD drive, count; + DWORD dwDriveMap; + LPSTR p; + + dwDriveMap = GetLogicalDrives(); + + for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++) + { + if (dwDriveMap & (1< nBufferLength) return ((count * 4) + 1); + + p = lpBuffer; + + for (drive = 0; drive < MAX_DOS_DRIVES; drive++) + if (dwDriveMap & (1< nBufferLength) return ((count * 4) + 1); + + p = lpBuffer; + for (drive = 0; drive < MAX_DOS_DRIVES; drive++) + if (dwDriveMap & (1<QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsFullSize.CallerAvailableAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfBytes != NULL) + { + lpTotalNumberOfBytes->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsFullSize.TotalAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfFreeBytes != NULL) + { + lpTotalNumberOfFreeBytes->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsFullSize.ActualAvailableAllocationUnits.QuadPart; + } + + return TRUE; + } + } + + Status = NtQueryVolumeInformationFile(hFile, + &IoStatusBlock, + &FsInfo.FsSize, + sizeof(FsInfo.FsSize), + FileFsSizeInformation); + + /* Close the handle before returning data + to avoid a handle leak in case of a fault! */ + CloseHandle(hFile); + + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError (Status); + return FALSE; + } + + BytesPerCluster.QuadPart = + FsInfo.FsSize.BytesPerSector * FsInfo.FsSize.SectorsPerAllocationUnit; + + if (lpFreeBytesAvailableToCaller) + { + lpFreeBytesAvailableToCaller->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfBytes) + { + lpTotalNumberOfBytes->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsSize.TotalAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfFreeBytes) + { + lpTotalNumberOfFreeBytes->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart; + } + + return TRUE; +} + +/* + * @implemented + */ +UINT +WINAPI +GetDriveTypeA(IN LPCSTR lpRootPathName) +{ + PWCHAR RootPathNameW; + + if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE))) + return DRIVE_UNKNOWN; + + return GetDriveTypeW(RootPathNameW); +} + +/* + * @implemented + */ +UINT +WINAPI +GetDriveTypeW(IN LPCWSTR lpRootPathName) +{ + FILE_FS_DEVICE_INFORMATION FileFsDevice; + IO_STATUS_BLOCK IoStatusBlock; + + HANDLE hFile; + NTSTATUS errCode; + + hFile = InternalOpenDirW(lpRootPathName, FALSE); + if (hFile == INVALID_HANDLE_VALUE) + { + return DRIVE_NO_ROOT_DIR; /* According to WINE regression tests */ + } + + errCode = NtQueryVolumeInformationFile (hFile, + &IoStatusBlock, + &FileFsDevice, + sizeof(FILE_FS_DEVICE_INFORMATION), + FileFsDeviceInformation); + if (!NT_SUCCESS(errCode)) + { + CloseHandle(hFile); + BaseSetLastNTError (errCode); + return 0; + } + CloseHandle(hFile); + + switch (FileFsDevice.DeviceType) + { + case FILE_DEVICE_CD_ROM: + case FILE_DEVICE_CD_ROM_FILE_SYSTEM: + return DRIVE_CDROM; + case FILE_DEVICE_VIRTUAL_DISK: + return DRIVE_RAMDISK; + case FILE_DEVICE_NETWORK_FILE_SYSTEM: + return DRIVE_REMOTE; + case FILE_DEVICE_DISK: + case FILE_DEVICE_DISK_FILE_SYSTEM: + if (FileFsDevice.Characteristics & FILE_REMOTE_DEVICE) + return DRIVE_REMOTE; + if (FileFsDevice.Characteristics & FILE_REMOVABLE_MEDIA) + return DRIVE_REMOVABLE; + return DRIVE_FIXED; + } + + ERR("Returning DRIVE_UNKNOWN for device type %d\n", FileFsDevice.DeviceType); + + return DRIVE_UNKNOWN; +} + +/* EOF */ diff --git a/dll/win32/kernel32/client/file/mntpoint.c b/dll/win32/kernel32/client/file/mntpoint.c new file mode 100644 index 00000000000..af0ae94df2f --- /dev/null +++ b/dll/win32/kernel32/client/file/mntpoint.c @@ -0,0 +1,394 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/kernel32/file/mntpoint.c + * PURPOSE: File volume mount point functions + * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) + * Erik Bos, Alexandre Julliard : + * GetLogicalDriveStringsA, + * GetLogicalDriveStringsW, GetLogicalDrives + * UPDATE HISTORY: + * Created 01/11/98 + */ +//WINE copyright notice: +/* + * DOS drives handling functions + * + * Copyright 1993 Erik Bos + * Copyright 1996 Alexandre Julliard + */ + +#include +#define NDEBUG +#include +DEBUG_CHANNEL(kernel32file); + +/** + * @name GetVolumeNameForVolumeMountPointW + * @implemented + * + * Return an unique volume name for a drive root or mount point. + * + * @param VolumeMountPoint + * Pointer to string that contains either root drive name or + * mount point name. + * @param VolumeName + * Pointer to buffer that is filled with resulting unique + * volume name on success. + * @param VolumeNameLength + * Size of VolumeName buffer in TCHARs. + * + * @return + * TRUE when the function succeeds and the VolumeName buffer is filled, + * FALSE otherwise. + */ +BOOL +WINAPI +GetVolumeNameForVolumeMountPointW(IN LPCWSTR VolumeMountPoint, + OUT LPWSTR VolumeName, + IN DWORD VolumeNameLength) +{ + UNICODE_STRING NtFileName; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE FileHandle; + IO_STATUS_BLOCK Iosb; + ULONG BufferLength; + PMOUNTDEV_NAME MountDevName; + PMOUNTMGR_MOUNT_POINT MountPoint; + ULONG MountPointSize; + PMOUNTMGR_MOUNT_POINTS MountPoints; + ULONG Index; + PUCHAR SymbolicLinkName; + BOOL Result; + NTSTATUS Status; + + if (!VolumeMountPoint || !VolumeMountPoint[0]) + { + SetLastError(ERROR_PATH_NOT_FOUND); + return FALSE; + } + + /* + * First step is to convert the passed volume mount point name to + * an NT acceptable name. + */ + + if (!RtlDosPathNameToNtPathName_U(VolumeMountPoint, &NtFileName, NULL, NULL)) + { + SetLastError(ERROR_PATH_NOT_FOUND); + return FALSE; + } + + if (NtFileName.Length > sizeof(WCHAR) && + NtFileName.Buffer[(NtFileName.Length / sizeof(WCHAR)) - 1] == '\\') + { + NtFileName.Length -= sizeof(WCHAR); + } + + /* + * Query mount point device name which we will later use for determining + * the volume name. + */ + + InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL); + Status = NtOpenFile(&FileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, &Iosb, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT); + RtlFreeUnicodeString(&NtFileName); + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + return FALSE; + } + + BufferLength = sizeof(MOUNTDEV_NAME) + 50 * sizeof(WCHAR); + do + { + MountDevName = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); + if (MountDevName == NULL) + { + NtClose(FileHandle); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, + IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, + NULL, 0, MountDevName, BufferLength); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(GetProcessHeap(), 0, MountDevName); + if (Status == STATUS_BUFFER_OVERFLOW) + { + BufferLength = sizeof(MOUNTDEV_NAME) + MountDevName->NameLength; + continue; + } + else + { + NtClose(FileHandle); + BaseSetLastNTError(Status); + return FALSE; + } + } + } + while (!NT_SUCCESS(Status)); + + NtClose(FileHandle); + + /* + * Get the mount point information from mount manager. + */ + + MountPointSize = MountDevName->NameLength + sizeof(MOUNTMGR_MOUNT_POINT); + MountPoint = RtlAllocateHeap(GetProcessHeap(), 0, MountPointSize); + if (MountPoint == NULL) + { + RtlFreeHeap(GetProcessHeap(), 0, MountDevName); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + RtlZeroMemory(MountPoint, sizeof(MOUNTMGR_MOUNT_POINT)); + MountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT); + MountPoint->DeviceNameLength = MountDevName->NameLength; + RtlCopyMemory(MountPoint + 1, MountDevName->Name, MountDevName->NameLength); + RtlFreeHeap(RtlGetProcessHeap(), 0, MountDevName); + + RtlInitUnicodeString(&NtFileName, L"\\??\\MountPointManager"); + InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL); + Status = NtOpenFile(&FileHandle, FILE_GENERIC_READ, &ObjectAttributes, + &Iosb, FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); + return FALSE; + } + + BufferLength = sizeof(MOUNTMGR_MOUNT_POINTS); + do + { + MountPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); + if (MountPoints == NULL) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); + NtClose(FileHandle); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, + IOCTL_MOUNTMGR_QUERY_POINTS, + MountPoint, MountPointSize, + MountPoints, BufferLength); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_BUFFER_OVERFLOW) + { + BufferLength = MountPoints->Size; + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); + continue; + } + else if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); + NtClose(FileHandle); + BaseSetLastNTError(Status); + return FALSE; + } + } + } + while (!NT_SUCCESS(Status)); + + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); + NtClose(FileHandle); + + /* + * Now we've gathered info about all mount points mapped to our device, so + * select the correct one and copy it into the output buffer. + */ + + for (Index = 0; Index < MountPoints->NumberOfMountPoints; Index++) + { + MountPoint = MountPoints->MountPoints + Index; + SymbolicLinkName = (PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset; + + /* + * Check for "\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\" + * (with the last slash being optional) style symbolic links. + */ + + if (MountPoint->SymbolicLinkNameLength == 48 * sizeof(WCHAR) || + (MountPoint->SymbolicLinkNameLength == 49 * sizeof(WCHAR) && + SymbolicLinkName[48] == L'\\')) + { + if (RtlCompareMemory(SymbolicLinkName, L"\\??\\Volume{", + 11 * sizeof(WCHAR)) == 11 * sizeof(WCHAR) && + SymbolicLinkName[19] == L'-' && SymbolicLinkName[24] == L'-' && + SymbolicLinkName[29] == L'-' && SymbolicLinkName[34] == L'-' && + SymbolicLinkName[47] == L'}') + { + if (VolumeNameLength >= MountPoint->SymbolicLinkNameLength / sizeof(WCHAR)) + { + RtlCopyMemory(VolumeName, + (PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset, + MountPoint->SymbolicLinkNameLength); + VolumeName[1] = L'\\'; + Result = TRUE; + } + else + { + SetLastError(ERROR_FILENAME_EXCED_RANGE); + Result = FALSE; + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); + + return Result; + } + } + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); + SetLastError(ERROR_INVALID_PARAMETER); + + return FALSE; +} + +/* + * @implemented (Wine 13 sep 2008) + */ +BOOL +WINAPI +GetVolumeNameForVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint, + IN LPSTR lpszVolumeName, + IN DWORD cchBufferLength) +{ + BOOL ret; + WCHAR volumeW[50], *pathW = NULL; + DWORD len = min( sizeof(volumeW) / sizeof(WCHAR), cchBufferLength ); + + TRACE("(%s, %p, %x)\n", debugstr_a(lpszVolumeMountPoint), lpszVolumeName, cchBufferLength); + + if (!lpszVolumeMountPoint || !(pathW = FilenameA2W( lpszVolumeMountPoint, TRUE ))) + return FALSE; + + if ((ret = GetVolumeNameForVolumeMountPointW( pathW, volumeW, len ))) + FilenameW2A_N( lpszVolumeName, len, volumeW, -1 ); + + RtlFreeHeap( RtlGetProcessHeap(), 0, pathW ); + return ret; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +SetVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint, + IN LPCWSTR lpszVolumeName) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +SetVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint, + IN LPCSTR lpszVolumeName) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +DeleteVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +DeleteVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +HANDLE +WINAPI +FindFirstVolumeMountPointW(IN LPCWSTR lpszRootPathName, + IN LPWSTR lpszVolumeMountPoint, + IN DWORD cchBufferLength) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +HANDLE +WINAPI +FindFirstVolumeMountPointA(IN LPCSTR lpszRootPathName, + IN LPSTR lpszVolumeMountPoint, + IN DWORD cchBufferLength) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +FindNextVolumeMountPointA(IN HANDLE hFindVolumeMountPoint, + IN LPSTR lpszVolumeMountPoint, + DWORD cchBufferLength) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +FindNextVolumeMountPointW(IN HANDLE hFindVolumeMountPoint, + IN LPWSTR lpszVolumeMountPoint, + DWORD cchBufferLength) +{ + STUB; + return 0; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +FindVolumeMountPointClose(IN HANDLE hFindVolumeMountPoint) +{ + STUB; + return 0; +} + +/* EOF */ diff --git a/dll/win32/kernel32/client/file/volume.c b/dll/win32/kernel32/client/file/volume.c index 62cc81bbf89..dedfb1c05b1 100644 --- a/dll/win32/kernel32/client/file/volume.c +++ b/dll/win32/kernel32/client/file/volume.c @@ -23,477 +23,66 @@ #include DEBUG_CHANNEL(kernel32file); -#define MAX_DOS_DRIVES 26 - - -static HANDLE -InternalOpenDirW(LPCWSTR DirName, - BOOLEAN Write) +HANDLE +WINAPI +InternalOpenDirW(IN LPCWSTR DirName, + IN BOOLEAN Write) { - UNICODE_STRING NtPathU; - OBJECT_ATTRIBUTES ObjectAttributes; - NTSTATUS errCode; - IO_STATUS_BLOCK IoStatusBlock; - HANDLE hFile; + UNICODE_STRING NtPathU; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS errCode; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE hFile; - if (!RtlDosPathNameToNtPathName_U(DirName, - &NtPathU, - NULL, - NULL)) + if (!RtlDosPathNameToNtPathName_U(DirName, &NtPathU, NULL, NULL)) { - WARN("Invalid path\n"); - SetLastError(ERROR_BAD_PATHNAME); - return INVALID_HANDLE_VALUE; + WARN("Invalid path\n"); + SetLastError(ERROR_BAD_PATHNAME); + return INVALID_HANDLE_VALUE; } InitializeObjectAttributes(&ObjectAttributes, - &NtPathU, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); + &NtPathU, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); - errCode = NtCreateFile (&hFile, - Write ? FILE_GENERIC_WRITE : FILE_GENERIC_READ, - &ObjectAttributes, - &IoStatusBlock, - NULL, - 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_OPEN, - 0, - NULL, - 0); + errCode = NtCreateFile(&hFile, + Write ? FILE_GENERIC_WRITE : FILE_GENERIC_READ, + &ObjectAttributes, + &IoStatusBlock, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + 0, + NULL, + 0); - RtlFreeHeap(RtlGetProcessHeap(), - 0, - NtPathU.Buffer); + RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathU.Buffer); if (!NT_SUCCESS(errCode)) { - BaseSetLastNTError (errCode); - return INVALID_HANDLE_VALUE; + BaseSetLastNTError(errCode); + return INVALID_HANDLE_VALUE; } + return hFile; } - /* * @implemented */ -/* Synced to Wine-2008/12/28 */ -DWORD WINAPI -GetLogicalDriveStringsA(DWORD nBufferLength, - LPSTR lpBuffer) -{ - DWORD drive, count; - DWORD dwDriveMap; - LPSTR p; - - dwDriveMap = GetLogicalDrives(); - - for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++) - { - if (dwDriveMap & (1< nBufferLength) return ((count * 4) + 1); - - p = lpBuffer; - - for (drive = 0; drive < MAX_DOS_DRIVES; drive++) - if (dwDriveMap & (1< nBufferLength) return ((count * 4) + 1); - - p = lpBuffer; - for (drive = 0; drive < MAX_DOS_DRIVES; drive++) - if (dwDriveMap & (1<QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsFullSize.CallerAvailableAllocationUnits.QuadPart; - } - - if (lpTotalNumberOfBytes != NULL) - { - lpTotalNumberOfBytes->QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsFullSize.TotalAllocationUnits.QuadPart; - } - - if (lpTotalNumberOfFreeBytes != NULL) - { - lpTotalNumberOfFreeBytes->QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsFullSize.ActualAvailableAllocationUnits.QuadPart; - } - - return TRUE; - } - } - - Status = NtQueryVolumeInformationFile(hFile, - &IoStatusBlock, - &FsInfo.FsSize, - sizeof(FsInfo.FsSize), - FileFsSizeInformation); - - /* Close the handle before returning data - to avoid a handle leak in case of a fault! */ - CloseHandle(hFile); - - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError (Status); - return FALSE; - } - - BytesPerCluster.QuadPart = - FsInfo.FsSize.BytesPerSector * FsInfo.FsSize.SectorsPerAllocationUnit; - - if (lpFreeBytesAvailableToCaller) - { - lpFreeBytesAvailableToCaller->QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart; - } - - if (lpTotalNumberOfBytes) - { - lpTotalNumberOfBytes->QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsSize.TotalAllocationUnits.QuadPart; - } - - if (lpTotalNumberOfFreeBytes) - { - lpTotalNumberOfFreeBytes->QuadPart = - BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart; - } - - return TRUE; -} - - -/* - * @implemented - */ -UINT WINAPI -GetDriveTypeA(LPCSTR lpRootPathName) -{ - PWCHAR RootPathNameW; - - if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE))) - return DRIVE_UNKNOWN; - - return GetDriveTypeW(RootPathNameW); -} - - -/* - * @implemented - */ -UINT WINAPI -GetDriveTypeW(LPCWSTR lpRootPathName) -{ - FILE_FS_DEVICE_INFORMATION FileFsDevice; - IO_STATUS_BLOCK IoStatusBlock; - - HANDLE hFile; - NTSTATUS errCode; - - hFile = InternalOpenDirW(lpRootPathName, FALSE); - if (hFile == INVALID_HANDLE_VALUE) - { - return DRIVE_NO_ROOT_DIR; /* According to WINE regression tests */ - } - - errCode = NtQueryVolumeInformationFile (hFile, - &IoStatusBlock, - &FileFsDevice, - sizeof(FILE_FS_DEVICE_INFORMATION), - FileFsDeviceInformation); - if (!NT_SUCCESS(errCode)) - { - CloseHandle(hFile); - BaseSetLastNTError (errCode); - return 0; - } - CloseHandle(hFile); - - switch (FileFsDevice.DeviceType) - { - case FILE_DEVICE_CD_ROM: - case FILE_DEVICE_CD_ROM_FILE_SYSTEM: - return DRIVE_CDROM; - case FILE_DEVICE_VIRTUAL_DISK: - return DRIVE_RAMDISK; - case FILE_DEVICE_NETWORK_FILE_SYSTEM: - return DRIVE_REMOTE; - case FILE_DEVICE_DISK: - case FILE_DEVICE_DISK_FILE_SYSTEM: - if (FileFsDevice.Characteristics & FILE_REMOTE_DEVICE) - return DRIVE_REMOTE; - if (FileFsDevice.Characteristics & FILE_REMOVABLE_MEDIA) - return DRIVE_REMOVABLE; - return DRIVE_FIXED; - } - - ERR("Returning DRIVE_UNKNOWN for device type %d\n", FileFsDevice.DeviceType); - - return DRIVE_UNKNOWN; -} - - -/* - * @implemented - */ -BOOL WINAPI -GetVolumeInformationA( - LPCSTR lpRootPathName, - LPSTR lpVolumeNameBuffer, - DWORD nVolumeNameSize, - LPDWORD lpVolumeSerialNumber, - LPDWORD lpMaximumComponentLength, - LPDWORD lpFileSystemFlags, - LPSTR lpFileSystemNameBuffer, - DWORD nFileSystemNameSize - ) +BOOL +WINAPI +GetVolumeInformationA(IN LPCSTR lpRootPathName, + IN LPSTR lpVolumeNameBuffer, + IN DWORD nVolumeNameSize, + OUT LPDWORD lpVolumeSerialNumber OPTIONAL, + OUT LPDWORD lpMaximumComponentLength OPTIONAL, + OUT LPDWORD lpFileSystemFlags OPTIONAL, + OUT LPSTR lpFileSystemNameBuffer OPTIONAL, + IN DWORD nFileSystemNameSize) { UNICODE_STRING FileSystemNameU; UNICODE_STRING VolumeNameU = { 0, 0, NULL }; @@ -622,17 +211,16 @@ FailNoMem: /* * @implemented */ -BOOL WINAPI -GetVolumeInformationW( - LPCWSTR lpRootPathName, - LPWSTR lpVolumeNameBuffer, - DWORD nVolumeNameSize, - LPDWORD lpVolumeSerialNumber, - LPDWORD lpMaximumComponentLength, - LPDWORD lpFileSystemFlags, - LPWSTR lpFileSystemNameBuffer, - DWORD nFileSystemNameSize - ) +BOOL +WINAPI +GetVolumeInformationW(IN LPCWSTR lpRootPathName, + IN LPWSTR lpVolumeNameBuffer, + IN DWORD nVolumeNameSize, + OUT LPDWORD lpVolumeSerialNumber OPTIONAL, + OUT LPDWORD lpMaximumComponentLength OPTIONAL, + OUT LPDWORD lpFileSystemFlags OPTIONAL, + OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, + IN DWORD nFileSystemNameSize) { PFILE_FS_VOLUME_INFORMATION FileFsVolume; PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute; @@ -734,16 +322,13 @@ GetVolumeInformationW( return TRUE; } - /* * @implemented */ BOOL WINAPI -SetVolumeLabelA ( - LPCSTR lpRootPathName, - LPCSTR lpVolumeName /* NULL if deleting label */ - ) +SetVolumeLabelA(IN LPCSTR lpRootPathName, + IN LPCSTR lpVolumeName OPTIONAL) /* NULL if deleting label */ { PWCHAR RootPathNameW; PWCHAR VolumeNameW = NULL; @@ -771,15 +356,13 @@ SetVolumeLabelA ( return Result; } - /* * @implemented */ -BOOL WINAPI -SetVolumeLabelW( - LPCWSTR lpRootPathName, - LPCWSTR lpVolumeName /* NULL if deleting label */ - ) +BOOL +WINAPI +SetVolumeLabelW(IN LPCWSTR lpRootPathName, + IN LPCWSTR lpVolumeName OPTIONAL) /* NULL if deleting label */ { PFILE_FS_LABEL_INFORMATION LabelInfo; IO_STATUS_BLOCK IoStatusBlock; @@ -834,276 +417,13 @@ SetVolumeLabelW( return TRUE; } -/** - * @name GetVolumeNameForVolumeMountPointW - * - * Return an unique volume name for a drive root or mount point. - * - * @param VolumeMountPoint - * Pointer to string that contains either root drive name or - * mount point name. - * @param VolumeName - * Pointer to buffer that is filled with resulting unique - * volume name on success. - * @param VolumeNameLength - * Size of VolumeName buffer in TCHARs. - * - * @return - * TRUE when the function succeeds and the VolumeName buffer is filled, - * FALSE otherwise. - */ - -BOOL WINAPI -GetVolumeNameForVolumeMountPointW( - IN LPCWSTR VolumeMountPoint, - OUT LPWSTR VolumeName, - IN DWORD VolumeNameLength) -{ - UNICODE_STRING NtFileName; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE FileHandle; - IO_STATUS_BLOCK Iosb; - ULONG BufferLength; - PMOUNTDEV_NAME MountDevName; - PMOUNTMGR_MOUNT_POINT MountPoint; - ULONG MountPointSize; - PMOUNTMGR_MOUNT_POINTS MountPoints; - ULONG Index; - PUCHAR SymbolicLinkName; - BOOL Result; - NTSTATUS Status; - - if (!VolumeMountPoint || !VolumeMountPoint[0]) - { - SetLastError(ERROR_PATH_NOT_FOUND); - return FALSE; - } - - /* - * First step is to convert the passed volume mount point name to - * an NT acceptable name. - */ - - if (!RtlDosPathNameToNtPathName_U(VolumeMountPoint, &NtFileName, NULL, NULL)) - { - SetLastError(ERROR_PATH_NOT_FOUND); - return FALSE; - } - - if (NtFileName.Length > sizeof(WCHAR) && - NtFileName.Buffer[(NtFileName.Length / sizeof(WCHAR)) - 1] == '\\') - { - NtFileName.Length -= sizeof(WCHAR); - } - - /* - * Query mount point device name which we will later use for determining - * the volume name. - */ - - InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL); - Status = NtOpenFile(&FileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, - &ObjectAttributes, &Iosb, - FILE_SHARE_READ | FILE_SHARE_WRITE, - FILE_SYNCHRONOUS_IO_NONALERT); - RtlFreeUnicodeString(&NtFileName); - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError(Status); - return FALSE; - } - - BufferLength = sizeof(MOUNTDEV_NAME) + 50 * sizeof(WCHAR); - do - { - MountDevName = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); - if (MountDevName == NULL) - { - NtClose(FileHandle); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, - IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, - NULL, 0, MountDevName, BufferLength); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(GetProcessHeap(), 0, MountDevName); - if (Status == STATUS_BUFFER_OVERFLOW) - { - BufferLength = sizeof(MOUNTDEV_NAME) + MountDevName->NameLength; - continue; - } - else - { - NtClose(FileHandle); - BaseSetLastNTError(Status); - return FALSE; - } - } - } - while (!NT_SUCCESS(Status)); - - NtClose(FileHandle); - - /* - * Get the mount point information from mount manager. - */ - - MountPointSize = MountDevName->NameLength + sizeof(MOUNTMGR_MOUNT_POINT); - MountPoint = RtlAllocateHeap(GetProcessHeap(), 0, MountPointSize); - if (MountPoint == NULL) - { - RtlFreeHeap(GetProcessHeap(), 0, MountDevName); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - RtlZeroMemory(MountPoint, sizeof(MOUNTMGR_MOUNT_POINT)); - MountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT); - MountPoint->DeviceNameLength = MountDevName->NameLength; - RtlCopyMemory(MountPoint + 1, MountDevName->Name, MountDevName->NameLength); - RtlFreeHeap(RtlGetProcessHeap(), 0, MountDevName); - - RtlInitUnicodeString(&NtFileName, L"\\??\\MountPointManager"); - InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL); - Status = NtOpenFile(&FileHandle, FILE_GENERIC_READ, &ObjectAttributes, - &Iosb, FILE_SHARE_READ | FILE_SHARE_WRITE, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError(Status); - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); - return FALSE; - } - - BufferLength = sizeof(MOUNTMGR_MOUNT_POINTS); - do - { - MountPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); - if (MountPoints == NULL) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); - NtClose(FileHandle); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, - IOCTL_MOUNTMGR_QUERY_POINTS, - MountPoint, MountPointSize, - MountPoints, BufferLength); - if (!NT_SUCCESS(Status)) - { - if (Status == STATUS_BUFFER_OVERFLOW) - { - BufferLength = MountPoints->Size; - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); - continue; - } - else if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); - NtClose(FileHandle); - BaseSetLastNTError(Status); - return FALSE; - } - } - } - while (!NT_SUCCESS(Status)); - - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); - NtClose(FileHandle); - - /* - * Now we've gathered info about all mount points mapped to our device, so - * select the correct one and copy it into the output buffer. - */ - - for (Index = 0; Index < MountPoints->NumberOfMountPoints; Index++) - { - MountPoint = MountPoints->MountPoints + Index; - SymbolicLinkName = (PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset; - - /* - * Check for "\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\" - * (with the last slash being optional) style symbolic links. - */ - - if (MountPoint->SymbolicLinkNameLength == 48 * sizeof(WCHAR) || - (MountPoint->SymbolicLinkNameLength == 49 * sizeof(WCHAR) && - SymbolicLinkName[48] == L'\\')) - { - if (RtlCompareMemory(SymbolicLinkName, L"\\??\\Volume{", - 11 * sizeof(WCHAR)) == 11 * sizeof(WCHAR) && - SymbolicLinkName[19] == L'-' && SymbolicLinkName[24] == L'-' && - SymbolicLinkName[29] == L'-' && SymbolicLinkName[34] == L'-' && - SymbolicLinkName[47] == L'}') - { - if (VolumeNameLength >= MountPoint->SymbolicLinkNameLength / sizeof(WCHAR)) - { - RtlCopyMemory(VolumeName, - (PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset, - MountPoint->SymbolicLinkNameLength); - VolumeName[1] = L'\\'; - Result = TRUE; - } - else - { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - Result = FALSE; - } - - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); - - return Result; - } - } - } - - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); - SetLastError(ERROR_INVALID_PARAMETER); - - return FALSE; -} - -/* - * @implemented (Wine 13 sep 2008) - */ -BOOL -WINAPI -GetVolumeNameForVolumeMountPointA( - LPCSTR lpszVolumeMountPoint, - LPSTR lpszVolumeName, - DWORD cchBufferLength - ) -{ - BOOL ret; - WCHAR volumeW[50], *pathW = NULL; - DWORD len = min( sizeof(volumeW) / sizeof(WCHAR), cchBufferLength ); - - TRACE("(%s, %p, %x)\n", debugstr_a(lpszVolumeMountPoint), lpszVolumeName, cchBufferLength); - - if (!lpszVolumeMountPoint || !(pathW = FilenameA2W( lpszVolumeMountPoint, TRUE ))) - return FALSE; - - if ((ret = GetVolumeNameForVolumeMountPointW( pathW, volumeW, len ))) - FilenameW2A_N( lpszVolumeName, len, volumeW, -1 ); - - RtlFreeHeap( RtlGetProcessHeap(), 0, pathW ); - return ret; -} - /* * @implemented (Wine 13 sep 2008) */ HANDLE WINAPI -FindFirstVolumeW( - LPWSTR volume, - DWORD len - ) +FindFirstVolumeW(IN LPWSTR volume, + IN DWORD len) { DWORD size = 1024; HANDLE mgr = CreateFileW( MOUNTMGR_DOS_DEVICE_NAME, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, @@ -1149,10 +469,8 @@ FindFirstVolumeW( */ HANDLE WINAPI -FindFirstVolumeA( - LPSTR volume, - DWORD len - ) +FindFirstVolumeA(IN LPSTR volume, + IN DWORD len) { WCHAR *buffer = NULL; HANDLE handle; @@ -1184,9 +502,7 @@ FindFirstVolumeA( */ BOOL WINAPI -FindVolumeClose( - HANDLE hFindVolume - ) +FindVolumeClose(IN HANDLE hFindVolume) { return RtlFreeHeap(RtlGetProcessHeap(), 0, hFindVolume); } @@ -1196,9 +512,9 @@ FindVolumeClose( */ BOOL WINAPI -GetVolumePathNameA(LPCSTR lpszFileName, - LPSTR lpszVolumePathName, - DWORD cchBufferLength) +GetVolumePathNameA(IN LPCSTR lpszFileName, + IN LPSTR lpszVolumePathName, + IN DWORD cchBufferLength) { PWCHAR FileNameW = NULL; WCHAR VolumePathName[MAX_PATH]; @@ -1223,9 +539,9 @@ GetVolumePathNameA(LPCSTR lpszFileName, */ BOOL WINAPI -GetVolumePathNameW(LPCWSTR lpszFileName, - LPWSTR lpszVolumePathName, - DWORD cchBufferLength) +GetVolumePathNameW(IN LPCWSTR lpszFileName, + IN LPWSTR lpszVolumePathName, + IN DWORD cchBufferLength) { DWORD PathLength; UNICODE_STRING UnicodeFilePath; @@ -1329,57 +645,14 @@ Cleanup2: return Result; } - -/* - * @unimplemented - */ -BOOL -WINAPI -SetVolumeMountPointW( - LPCWSTR lpszVolumeMountPoint, - LPCWSTR lpszVolumeName - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -BOOL -WINAPI -DeleteVolumeMountPointA( - LPCSTR lpszVolumeMountPoint - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -HANDLE -WINAPI -FindFirstVolumeMountPointA( - LPCSTR lpszRootPathName, - LPSTR lpszVolumeMountPoint, - DWORD cchBufferLength - ) -{ - STUB; - return 0; -} - /* * @implemented */ BOOL WINAPI -FindNextVolumeA(HANDLE handle, - LPSTR volume, - DWORD len) +FindNextVolumeA(IN HANDLE handle, + IN LPSTR volume, + IN DWORD len) { WCHAR *buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, len * sizeof(WCHAR)); BOOL ret; @@ -1399,102 +672,14 @@ FindNextVolumeA(HANDLE handle, return ret; } -/* - * @unimplemented - */ -BOOL -WINAPI -FindNextVolumeMountPointA( - HANDLE hFindVolumeMountPoint, - LPSTR lpszVolumeMountPoint, - DWORD cchBufferLength - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -BOOL -WINAPI -GetVolumePathNamesForVolumeNameA( - LPCSTR lpszVolumeName, - LPSTR lpszVolumePathNames, - DWORD cchBufferLength, - PDWORD lpcchReturnLength - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -BOOL -WINAPI -SetVolumeMountPointA( - LPCSTR lpszVolumeMountPoint, - LPCSTR lpszVolumeName - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -BOOL -WINAPI -FindVolumeMountPointClose( - HANDLE hFindVolumeMountPoint - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -BOOL -WINAPI -DeleteVolumeMountPointW( - LPCWSTR lpszVolumeMountPoint - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ -HANDLE -WINAPI -FindFirstVolumeMountPointW( - LPCWSTR lpszRootPathName, - LPWSTR lpszVolumeMountPoint, - DWORD cchBufferLength - ) -{ - STUB; - return 0; -} - /* * @implemented */ BOOL WINAPI -FindNextVolumeW( - HANDLE handle, - LPWSTR volume, - DWORD len - ) +FindNextVolumeW(IN HANDLE handle, + IN LPWSTR volume, + IN DWORD len) { MOUNTMGR_MOUNT_POINTS *data = handle; @@ -1527,31 +712,28 @@ FindNextVolumeW( */ BOOL WINAPI -FindNextVolumeMountPointW( - HANDLE hFindVolumeMountPoint, - LPWSTR lpszVolumeMountPoint, - DWORD cchBufferLength - ) +GetVolumePathNamesForVolumeNameA(IN LPCSTR lpszVolumeName, + IN LPSTR lpszVolumePathNames, + IN DWORD cchBufferLength, + OUT PDWORD lpcchReturnLength) { STUB; return 0; } + /* * @unimplemented */ BOOL WINAPI -GetVolumePathNamesForVolumeNameW( - LPCWSTR lpszVolumeName, - LPWSTR lpszVolumePathNames, - DWORD cchBufferLength, - PDWORD lpcchReturnLength - ) +GetVolumePathNamesForVolumeNameW(IN LPCWSTR lpszVolumeName, + IN LPWSTR lpszVolumePathNames, + IN DWORD cchBufferLength, + OUT PDWORD lpcchReturnLength) { STUB; return 0; } - /* EOF */ diff --git a/dll/win32/kernel32/client/path.c b/dll/win32/kernel32/client/path.c index a6e1692a909..4b73357d745 100644 --- a/dll/win32/kernel32/client/path.c +++ b/dll/win32/kernel32/client/path.c @@ -401,7 +401,7 @@ WINAPI BaseComputeProcessExePath(IN LPWSTR FullPath) { PBASE_SEARCH_PATH_TYPE PathOrder; - DPRINT1("Computing EXE path: %wZ\n", FullPath); + DPRINT1("Computing EXE path: %S\n", FullPath); /* Check if we should use the current directory */ PathOrder = NeedCurrentDirectoryForExePathW(FullPath) ? diff --git a/dll/win32/kernel32/client/proc.c b/dll/win32/kernel32/client/proc.c index ab030f3413e..754ae9dd2a7 100644 --- a/dll/win32/kernel32/client/proc.c +++ b/dll/win32/kernel32/client/proc.c @@ -53,7 +53,6 @@ RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle); /* FUNCTIONS ****************************************************************/ -// NOTE: Code duplicated from BasepDuplicateAndWriteHandle VOID WINAPI StuffStdHandle(IN HANDLE ProcessHandle, @@ -62,31 +61,35 @@ StuffStdHandle(IN HANDLE ProcessHandle, { NTSTATUS Status; HANDLE DuplicatedHandle; - SIZE_T Dummy; + SIZE_T NumberOfBytesWritten; + + /* If there is no handle to duplicate, return immediately */ + if (!StandardHandle) return; /* Duplicate the handle */ Status = NtDuplicateObject(NtCurrentProcess(), StandardHandle, ProcessHandle, &DuplicatedHandle, - 0, 0, - DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES); - if (NT_SUCCESS(Status)) - { - /* Write it */ - NtWriteVirtualMemory(ProcessHandle, - Address, - &DuplicatedHandle, - sizeof(HANDLE), - &Dummy); - } + 0, + 0, + DUPLICATE_SAME_ACCESS | + DUPLICATE_SAME_ATTRIBUTES); + if (!NT_SUCCESS(Status)) return; + + /* Write it */ + NtWriteVirtualMemory(ProcessHandle, + Address, + &DuplicatedHandle, + sizeof(HANDLE), + &NumberOfBytesWritten); } BOOLEAN WINAPI -BuildSubSysCommandLine(IN LPWSTR SubsystemName, - IN LPWSTR ApplicationName, - IN LPWSTR CommandLine, +BuildSubSysCommandLine(IN LPCWSTR SubsystemName, + IN LPCWSTR ApplicationName, + IN LPCWSTR CommandLine, OUT PUNICODE_STRING SubsysCommandLine) { UNICODE_STRING CommandLineString, ApplicationNameString; @@ -185,9 +188,9 @@ BasepConfigureAppCertDlls(IN PWSTR ValueName, NTSTATUS WINAPI -BasepIsProcessAllowed(IN PCHAR ApplicationName) +BasepIsProcessAllowed(IN LPWSTR ApplicationName) { - NTSTATUS Status; + NTSTATUS Status, Status1; PWCHAR Buffer; UINT Length; HMODULE TrustLibrary; @@ -251,19 +254,22 @@ BasepIsProcessAllowed(IN PCHAR ApplicationName) else { /* Other systems have a registry entry for this */ - Status = NtOpenKey(&KeyHandle, KEY_READ, &KeyAttributes); - if (NT_SUCCESS(Status)) + Status1 = NtOpenKey(&KeyHandle, KEY_READ, &KeyAttributes); + if (NT_SUCCESS(Status1)) { /* Close it, we'll query it through Rtl */ NtClose(KeyHandle); /* Do the query, which will call a special callback */ - Status = RtlQueryRegistryValues(2, + Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, L"Session Manager", BasepAppCertTable, - 0, - 0); - if (Status == 0xC0000034) Status = STATUS_SUCCESS; + NULL, + NULL); + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + Status = STATUS_SUCCESS; + } } } @@ -520,237 +526,6 @@ BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, return STATUS_SUCCESS; } -/* - * Creates the first Thread in a Proces - */ -HANDLE -WINAPI -BasepCreateFirstThread(HANDLE ProcessHandle, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - PSECTION_IMAGE_INFORMATION SectionImageInfo, - PCLIENT_ID ClientId, - DWORD dwCreationFlags) -{ - NTSTATUS Status; - OBJECT_ATTRIBUTES LocalObjectAttributes; - POBJECT_ATTRIBUTES ObjectAttributes; - CONTEXT Context; - INITIAL_TEB InitialTeb; - HANDLE hThread; - BASE_API_MESSAGE ApiMessage; - PBASE_CREATE_PROCESS CreateProcessRequest = &ApiMessage.Data.CreateProcessRequest; - - DPRINT("BasepCreateFirstThread. hProcess: %lx\n", ProcessHandle); - - /* Create the Thread's Stack */ - BaseCreateStack(ProcessHandle, - SectionImageInfo->MaximumStackSize, - SectionImageInfo->CommittedStackSize, - &InitialTeb); - - /* Create the Thread's Context */ - BaseInitializeContext(&Context, - NtCurrentPeb(), - SectionImageInfo->TransferAddress, - InitialTeb.StackBase, - 0); - - /* Convert the thread attributes */ - ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, - lpThreadAttributes, - NULL); - - /* Create the Kernel Thread Object */ - Status = NtCreateThread(&hThread, - THREAD_ALL_ACCESS, - ObjectAttributes, - ProcessHandle, - ClientId, - &Context, - &InitialTeb, - TRUE); - if (!NT_SUCCESS(Status)) - { - return NULL; - } - - /* Fill out the request to notify CSRSS */ - CreateProcessRequest->ClientId = *ClientId; - CreateProcessRequest->ProcessHandle = ProcessHandle; - CreateProcessRequest->ThreadHandle = hThread; - CreateProcessRequest->CreationFlags = dwCreationFlags; - - /* - * For GUI applications we turn on the 2nd bit. This also allows - * us to know whether or not this is a GUI or a TUI application. - */ - if (IMAGE_SUBSYSTEM_WINDOWS_GUI == SectionImageInfo->SubSystemType) - { - CreateProcessRequest->ProcessHandle = (HANDLE) - ((ULONG_PTR)CreateProcessRequest->ProcessHandle | 2); - } - - /* Call CSR */ - Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, - NULL, - CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateProcess), - sizeof(BASE_CREATE_PROCESS)); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to tell CSRSS about new process: %lx\n", Status); - return NULL; - } - - /* Success */ - return hThread; -} - -/* - * Converts ANSI to Unicode Environment - */ -PVOID -WINAPI -BasepConvertUnicodeEnvironment(OUT SIZE_T* EnvSize, - IN PVOID lpEnvironment) -{ - PCHAR pcScan; - ANSI_STRING AnsiEnv; - UNICODE_STRING UnicodeEnv; - NTSTATUS Status; - - DPRINT("BasepConvertUnicodeEnvironment\n"); - - /* Scan the environment to calculate its Unicode size */ - AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment; - while (*pcScan) - { - pcScan += strlen(pcScan) + 1; - } - - /* Create our ANSI String */ - if (pcScan == (PCHAR)lpEnvironment) - { - AnsiEnv.Length = 2 * sizeof(CHAR); - } - else - { - - AnsiEnv.Length = (USHORT)((ULONG_PTR)pcScan - (ULONG_PTR)lpEnvironment + sizeof(CHAR)); - } - AnsiEnv.MaximumLength = AnsiEnv.Length + 1; - - /* Allocate memory for the Unicode Environment */ - UnicodeEnv.Buffer = NULL; - *EnvSize = AnsiEnv.MaximumLength * sizeof(WCHAR); - Status = NtAllocateVirtualMemory(NtCurrentProcess(), - (PVOID)&UnicodeEnv.Buffer, - 0, - EnvSize, - MEM_COMMIT, - PAGE_READWRITE); - /* Failure */ - if (!NT_SUCCESS(Status)) - { - SetLastError(Status); - *EnvSize = 0; - return NULL; - } - - /* Use the allocated size */ - UnicodeEnv.MaximumLength = (USHORT)*EnvSize; - - /* Convert */ - RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE); - return UnicodeEnv.Buffer; -} - -/* - * Converts a Win32 Priority Class to NT - */ -ULONG -WINAPI -BasepConvertPriorityClass(IN ULONG dwCreationFlags) -{ - ULONG ReturnClass; - - if(dwCreationFlags & IDLE_PRIORITY_CLASS) - { - ReturnClass = PROCESS_PRIORITY_CLASS_IDLE; - } - else if(dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS) - { - ReturnClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; - } - else if(dwCreationFlags & NORMAL_PRIORITY_CLASS) - { - ReturnClass = PROCESS_PRIORITY_CLASS_NORMAL; - } - else if(dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS) - { - ReturnClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; - } - else if(dwCreationFlags & HIGH_PRIORITY_CLASS) - { - ReturnClass = PROCESS_PRIORITY_CLASS_HIGH; - } - else if(dwCreationFlags & REALTIME_PRIORITY_CLASS) - { - /* Check for Privilege First */ - if (BasepIsRealtimeAllowed(TRUE)) - { - ReturnClass = PROCESS_PRIORITY_CLASS_REALTIME; - } - else - { - ReturnClass = PROCESS_PRIORITY_CLASS_HIGH; - } - } - else - { - ReturnClass = PROCESS_PRIORITY_CLASS_INVALID; - } - - return ReturnClass; -} - -/* - * Duplicates a standard handle and writes it where requested. - */ -// NOTE: Code duplicated from StuffStdHandle -VOID -WINAPI -BasepDuplicateAndWriteHandle(IN HANDLE ProcessHandle, - IN HANDLE StandardHandle, - IN PHANDLE Address) -{ - NTSTATUS Status; - HANDLE DuplicatedHandle; - SIZE_T Dummy; - - DPRINT("BasepDuplicateAndWriteHandle. hProcess: %lx, Handle: %lx," - "Address: %p\n", ProcessHandle, StandardHandle, Address); - - /* Don't touch Console Handles */ - if (IsConsoleHandle(StandardHandle)) return; - - /* Duplicate the handle */ - Status = NtDuplicateObject(NtCurrentProcess(), - StandardHandle, - ProcessHandle, - &DuplicatedHandle, - 0, 0, - DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES); - if (NT_SUCCESS(Status)) - { - /* Write it */ - NtWriteVirtualMemory(ProcessHandle, - Address, - &DuplicatedHandle, - sizeof(HANDLE), - &Dummy); - } -} - BOOLEAN WINAPI BasePushProcessParameters(IN ULONG ParameterFlags, @@ -855,6 +630,8 @@ BasePushProcessParameters(IN ULONG ParameterFlags, /* Create the Parameter Block */ ProcessParameters = NULL; + DPRINT1("Image Name: %wZ Dll Path: %wZ current directory: %wZ, CmdLine: %wZ, Title: %wZ, Desktop: %wZ, Shell: %wZ, Runtime: %wZ\n", + &ImageName, &DllPath, &CurrentDirectory, &CommandLine, &Title, &Desktop, &Shell, &Runtime); Status = RtlCreateProcessParameters(&ProcessParameters, &ImageName, &DllPath, @@ -993,16 +770,16 @@ BasePushProcessParameters(IN ULONG ParameterFlags, ProcessParameters->ConsoleFlags = 1; } - /* See if the first 1MB should be reserved */ + /* Check if there's a .local file present */ if (ParameterFlags & 1) { - ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB; + ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH; } - /* See if the first 16MB should be reserved */ + /* Check if we failed to open the IFEO key */ if (ParameterFlags & 2) { - ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_16MB; + ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING; } /* Allocate memory for the parameter block */ @@ -1096,7 +873,7 @@ Quickie: if (ProcessParameters) RtlDestroyProcessParameters(ProcessParameters); return Result; FailPath: - DPRINT1("Failure to create proecss parameters: %lx\n", Status); + DPRINT1("Failure to create process parameters: %lx\n", Status); BaseSetLastNTError(Status); Result = FALSE; goto Quickie; @@ -2481,91 +2258,217 @@ ProcessIdToSessionId(IN DWORD dwProcessId, return FALSE; } + +#define AddToHandle(x,y) (x) = (HANDLE)((ULONG_PTR)(x) | (y)); +#define RemoveFromHandle(x,y) (x) = (HANDLE)((ULONG_PTR)(x) & ~(y)); +C_ASSERT(PROCESS_PRIORITY_CLASS_REALTIME == (PROCESS_PRIORITY_CLASS_HIGH + 1)); + /* * @implemented */ BOOL WINAPI -CreateProcessInternalW(HANDLE hToken, - LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation, - PHANDLE hNewToken) +CreateProcessInternalW(IN HANDLE hUserToken, + IN LPCWSTR lpApplicationName, + IN LPWSTR lpCommandLine, + IN LPSECURITY_ATTRIBUTES lpProcessAttributes, + IN LPSECURITY_ATTRIBUTES lpThreadAttributes, + IN BOOL bInheritHandles, + IN DWORD dwCreationFlags, + IN LPVOID lpEnvironment, + IN LPCWSTR lpCurrentDirectory, + IN LPSTARTUPINFOW lpStartupInfo, + IN LPPROCESS_INFORMATION lpProcessInformation, + OUT PHANDLE hNewToken) { - NTSTATUS Status; - PROCESS_PRIORITY_CLASS PriorityClass; - BOOLEAN FoundQuotes = FALSE; - BOOLEAN QuotesNeeded = FALSE; - BOOLEAN CmdLineIsAppName = FALSE; - UNICODE_STRING ApplicationName = { 0, 0, NULL }; + // + // Core variables used for creating the initial process and thread + // + SECURITY_ATTRIBUTES LocalThreadAttributes, LocalProcessAttributes; OBJECT_ATTRIBUTES LocalObjectAttributes; POBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hSection = NULL, hProcess = NULL, hThread = NULL, hDebug = NULL; - SECTION_IMAGE_INFORMATION SectionImageInfo; - LPWSTR CurrentDirectory = NULL; - LPWSTR CurrentDirectoryPart; - PROCESS_BASIC_INFORMATION ProcessBasicInfo; - STARTUPINFOW StartupInfo; - ULONG Dummy; - LPWSTR BatchCommandLine; - ULONG CmdLineLength; - UNICODE_STRING CommandLineString; - PWCHAR Extension; - LPWSTR QuotedCmdLine = NULL; - LPWSTR ScanString; - LPWSTR NullBuffer = NULL; - LPWSTR NameBuffer = NULL; - WCHAR SaveChar = 0; - ULONG RetVal; - UINT Error = 0; - UINT Length; - BOOLEAN SearchDone = FALSE; - BOOLEAN Escape = FALSE; + SECTION_IMAGE_INFORMATION ImageInformation; + IO_STATUS_BLOCK IoStatusBlock; CLIENT_ID ClientId; - PPEB OurPeb = NtCurrentPeb(); - PPEB RemotePeb; - SIZE_T EnvSize = 0; - BOOL Ret = FALSE; + ULONG NoWindow, RegionSize, StackSize, ImageMachine, ErrorCode, Flags; + ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse; + ULONG_PTR ErrorParameters[2]; + BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege; + BOOLEAN QuerySection, SkipSaferAndAppCompat; + CONTEXT Context; + BASE_API_MESSAGE CsrMsg; + PBASE_CREATE_PROCESS CreateProcessMsg; + PCSR_CAPTURE_BUFFER CaptureBuffer; + PVOID BaseAddress, PrivilegeState, RealTimePrivilegeState; + HANDLE DebugHandle, TokenHandle, JobHandle, KeyHandle, ThreadHandle; + HANDLE FileHandle, SectionHandle, ProcessHandle; + ULONG ResumeCount; + PROCESS_PRIORITY_CLASS PriorityClass; + NTSTATUS Status, Status1, ImageDbgStatus; + PPEB Peb, RemotePeb; + PTEB Teb; + INITIAL_TEB InitialTeb; + PVOID TibValue; + PIMAGE_NT_HEADERS NtHeaders; + STARTUPINFOW StartupInfo; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + UNICODE_STRING DebuggerString; + BOOL Result; + // + // Variables used for command-line and argument parsing + // + PCHAR pcScan; + SIZE_T n; + WCHAR SaveChar; + ULONG Length, CurdirLength, CmdQuoteLength; + ULONG CmdLineLength, ResultSize; + PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory; + PWCHAR NullBuffer, ScanString, NameBuffer, SearchPath, DebuggerCmdLine; + ANSI_STRING AnsiEnv; + UNICODE_STRING UnicodeEnv, PathName; + BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName, HasQuotes; WCHAR VdmPath[MAX_PATH]; - /* FIXME should process - * HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options - * key (see http://blogs.msdn.com/oldnewthing/archive/2005/12/19/505449.aspx) - */ + // + // Variables used for Fusion/SxS (Side-by-Side Assemblies) + // + RTL_PATH_TYPE SxsPathType, PathType; +#if _SXS_SUPPORT_ENABLED_ + PRTL_BUFFER ByteBuffer; + PRTL_UNICODE_STRING_BUFFER ThisBuffer, Buffer, SxsStaticBuffers[5]; + PRTL_UNICODE_STRING_BUFFER* BufferHead, SxsStringBuffer; + RTL_UNICODE_STRING_BUFFER SxsWin32ManifestPath, SxsNtManifestPath; + RTL_UNICODE_STRING_BUFFER SxsWin32PolicyPath, SxsNtPolicyPath; + RTL_UNICODE_STRING_BUFFER SxsWin32AssemblyDirectory; + BASE_MSG_SXS_HANDLES MappedHandles, Handles, FileHandles; + PVOID CapturedStrings[3]; + SXS_WIN32_NT_PATH_PAIR ExePathPair, ManifestPathPair, PolicyPathPair; + SXS_OVERRIDE_MANIFEST OverrideMannifest; + UNICODE_STRING FreeString, SxsNtExePath; + PWCHAR SxsConglomeratedBuffer, StaticBuffer; + ULONG ConglomeratedBufferSizeBytes, StaticBufferSize, i; +#endif + ULONG FusionFlags; - DPRINT("CreateProcessW: lpApplicationName: %S lpCommandLine: %S" - " lpEnvironment: %p lpCurrentDirectory: %S dwCreationFlags: %lx\n", - lpApplicationName, lpCommandLine, lpEnvironment, lpCurrentDirectory, - dwCreationFlags); + // + // Variables used for path conversion (and partially Fusion/SxS) + // + PWCHAR FilePart, PathBuffer, FreeBuffer; + BOOLEAN TranslationStatus; + RTL_RELATIVE_NAME_U SxsWin32RelativePath; + UNICODE_STRING PathBufferString, SxsWin32ExePath; - /* Flags we don't handle yet */ - if (dwCreationFlags & CREATE_SEPARATE_WOW_VDM) - { - DPRINT1("CREATE_SEPARATE_WOW_VDM not handled\n"); - } - if (dwCreationFlags & CREATE_SHARED_WOW_VDM) - { - DPRINT1("CREATE_SHARED_WOW_VDM not handled\n"); - } - if (dwCreationFlags & CREATE_FORCEDOS) - { - DPRINT1("CREATE_FORCEDOS not handled\n"); - } + // + // Variables used by Application Compatibility (and partially Fusion/SxS) + // + PVOID AppCompatSxsData, AppCompatData; + ULONG AppCompatSxsDataSize, AppCompatDataSize; + // + // Variables used by VDM (Virtual Dos Machine) and WOW32 (16-bit Support) + // + ULONG BinarySubType, VdmBinaryType, VdmTask, VdmReserve; + ULONG VdmUndoLevel; + BOOLEAN UseVdmReserve; + HANDLE VdmWaitObject; + ANSI_STRING VdmAnsiEnv; + UNICODE_STRING VdmString, VdmUnicodeEnv; + BOOLEAN IsWowApp; + PBASE_CHECK_VDM VdmMsg; - /* Fail on this flag, it's only valid with the WithLogonW function */ - if (dwCreationFlags & CREATE_PRESERVE_CODE_AUTHZ_LEVEL) - { - DPRINT1("Invalid flag used\n"); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + /* Zero out the initial core variables and handles */ + QuerySection = FALSE; + InJob = FALSE; + SkipSaferAndAppCompat = FALSE; + ParameterFlags = 0; + Flags = 0; + DebugHandle = NULL; + JobHandle = NULL; + TokenHandle = NULL; + FileHandle = NULL; + SectionHandle = NULL; + ProcessHandle = NULL; + ThreadHandle = NULL; + BaseAddress = (PVOID)1; + + /* Zero out initial SxS and Application Compatibility state */ + AppCompatData = NULL; + AppCompatDataSize = 0; + AppCompatSxsData = NULL; + AppCompatSxsDataSize = 0; + CaptureBuffer = NULL; +#if _SXS_SUPPORT_ENABLED_ + SxsConglomeratedBuffer = NULL; +#endif + FusionFlags = 0; + + /* Zero out initial parsing variables -- others are initialized later */ + DebuggerCmdLine = NULL; + PathBuffer = NULL; + SearchPath = NULL; + NullBuffer = 0; + FreeBuffer = NULL; + NameBuffer = NULL; + CurrentDirectory = NULL; + FilePart = NULL; + DebuggerString.Buffer = NULL; + HasQuotes = FALSE; + QuotedCmdLine = NULL; + + /* Zero out initial VDM state */ + VdmAnsiEnv.Buffer = NULL; + VdmUnicodeEnv.Buffer = NULL; + VdmString.Buffer = NULL; + VdmTask = 0; + VdmUndoLevel = 0; + VdmBinaryType = 0; + VdmReserve = 0; + VdmWaitObject = NULL; + UseVdmReserve = FALSE; + IsWowApp = FALSE; + + /* Set message structures */ + CreateProcessMsg = &CsrMsg.Data.CreateProcessRequest; + VdmMsg = &CsrMsg.Data.CheckVdm; + + /* Clear the more complex structures by zeroing out their entire memory */ + RtlZeroMemory(&Context, sizeof(Context)); +#if _SXS_SUPPORT_ENABLED_ + RtlZeroMemory(&FileHandles, sizeof(FileHandles)); + RtlZeroMemory(&MappedHandles, sizeof(MappedHandles)); + RtlZeroMemory(&Handles, sizeof(Handles)); +#endif + RtlZeroMemory(&CreateProcessMsg->Sxs, sizeof(CreateProcessMsg->Sxs)); + RtlZeroMemory(&LocalProcessAttributes, sizeof(LocalProcessAttributes)); + RtlZeroMemory(&LocalThreadAttributes, sizeof(LocalThreadAttributes)); + + /* Zero out output arguments as well */ + RtlZeroMemory(lpProcessInformation, sizeof(*lpProcessInformation)); + if (hNewToken) *hNewToken = NULL; + + /* Capture the special window flag */ + NoWindow = dwCreationFlags & CREATE_NO_WINDOW; + dwCreationFlags &= ~CREATE_NO_WINDOW; + +#if _SXS_SUPPORT_ENABLED_ + /* Setup the SxS static string arrays and buffers */ + SxsStaticBuffers[0] = &SxsWin32ManifestPath; + SxsStaticBuffers[1] = &SxsWin32PolicyPath; + SxsStaticBuffers[2] = &SxsWin32AssemblyDirectory; + SxsStaticBuffers[3] = &SxsNtManifestPath; + SxsStaticBuffers[4] = &SxsNtPolicyPath; + ExePathPair.Win32 = &SxsWin32ExePath; + ExePathPair.Nt = &SxsNtExePath; + ManifestPathPair.Win32 = &SxsWin32ManifestPath.String; + ManifestPathPair.Nt = &SxsNtManifestPath.String; + PolicyPathPair.Win32 = &SxsWin32PolicyPath.String; + PolicyPathPair.Nt = &SxsNtPolicyPath.String; +#endif + + DPRINT1("CreateProcessInternalW: %S %S %lx\n", lpApplicationName, lpCommandLine, dwCreationFlags); + + /* Finally, set our TEB and PEB */ + Teb = NtCurrentTeb(); + Peb = NtCurrentPeb(); /* This combination is illegal (see MSDN) */ if ((dwCreationFlags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)) == @@ -2576,453 +2479,1350 @@ CreateProcessInternalW(HANDLE hToken, return FALSE; } - /* Another illegal combo */ - if ((dwCreationFlags & (CREATE_SEPARATE_WOW_VDM | CREATE_SHARED_WOW_VDM)) == - (CREATE_SEPARATE_WOW_VDM | CREATE_SHARED_WOW_VDM)) + /* Convert the priority class */ + if (dwCreationFlags & IDLE_PRIORITY_CLASS) { - DPRINT1("Invalid flag combo used\n"); + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE; + } + else if (dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS) + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; + } + else if (dwCreationFlags & NORMAL_PRIORITY_CLASS) + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL; + } + else if (dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS) + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; + } + else if (dwCreationFlags & HIGH_PRIORITY_CLASS) + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; + } + else if (dwCreationFlags & REALTIME_PRIORITY_CLASS) + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; + PriorityClass.PriorityClass += (BasepIsRealtimeAllowed(FALSE) != NULL); + } + else + { + PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_INVALID; + } + + /* Done with the priority masks, so get rid of them */ + PriorityClass.Foreground = FALSE; + dwCreationFlags &= ~(NORMAL_PRIORITY_CLASS | + IDLE_PRIORITY_CLASS | + HIGH_PRIORITY_CLASS | + REALTIME_PRIORITY_CLASS | + BELOW_NORMAL_PRIORITY_CLASS | + ABOVE_NORMAL_PRIORITY_CLASS); + + /* You cannot request both a shared and a separate WoW VDM */ + if ((dwCreationFlags & CREATE_SEPARATE_WOW_VDM) && + (dwCreationFlags & CREATE_SHARED_WOW_VDM)) + { + /* Fail such nonsensical attempts */ + DPRINT1("Invalid WOW flags\n"); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - - if (lpCurrentDirectory) + else if (!(dwCreationFlags & CREATE_SHARED_WOW_VDM) && + (BaseStaticServerData->DefaultSeparateVDM)) { - if ((GetFileAttributesW(lpCurrentDirectory) == INVALID_FILE_ATTRIBUTES) || - !(GetFileAttributesW(lpCurrentDirectory) & FILE_ATTRIBUTE_DIRECTORY)) + /* A shared WoW VDM was not requested but system enforces separation */ + dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; + } + + /* If a shared WoW VDM is used, make sure the process isn't in a job */ + if (!(dwCreationFlags & CREATE_SEPARATE_WOW_VDM) && + (NtIsProcessInJob(NtCurrentProcess(), NULL))) + { + /* Remove the shared flag and add the separate flag */ + dwCreationFlags = (dwCreationFlags &~ CREATE_SHARED_WOW_VDM) | + CREATE_SEPARATE_WOW_VDM; + } + + /* Convert the environment */ + if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + { + /* Scan the environment to calculate its Unicode size */ + AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment; + while ((*pcScan) || (*(pcScan + 1))) ++pcScan; + + /* Create our ANSI String */ + AnsiEnv.Length = pcScan - (PCHAR)lpEnvironment + sizeof(ANSI_NULL); + AnsiEnv.MaximumLength = AnsiEnv.Length + sizeof(ANSI_NULL); + + /* Allocate memory for the Unicode Environment */ + UnicodeEnv.Buffer = NULL; + RegionSize = AnsiEnv.MaximumLength * sizeof(WCHAR); + Status = NtAllocateVirtualMemory(NtCurrentProcess(), + (PVOID)&UnicodeEnv.Buffer, + 0, + &RegionSize, + MEM_COMMIT, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) { - SetLastError(ERROR_DIRECTORY); + /* Fail */ + BaseSetLastNTError(Status); return FALSE; } + + /* Use the allocated size and convert */ + UnicodeEnv.MaximumLength = RegionSize; + Status = RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + NtFreeVirtualMemory(NtCurrentProcess(), + (PVOID)&UnicodeEnv.Buffer, + &RegionSize, + MEM_RELEASE); + BaseSetLastNTError(Status); + return FALSE; + } + + /* Now set the Unicode environment as the environment string pointer */ + lpEnvironment = UnicodeEnv.Buffer; } - /* - * We're going to modify and mask out flags and stuff in lpStartupInfo, - * so we'll use our own local copy for that. - */ + /* Make a copy of the caller's startup info since we'll modify it */ StartupInfo = *lpStartupInfo; - /* FIXME: Use default Separate/Shared VDM Flag */ - - /* If we are inside a Job, use Separate VDM so it won't escape the Job */ - if (!(dwCreationFlags & CREATE_SEPARATE_WOW_VDM)) - { - if (NtIsProcessInJob(NtCurrentProcess(), NULL)) - { - /* Remove the shared flag and add the separate flag. */ - dwCreationFlags = (dwCreationFlags &~ CREATE_SHARED_WOW_VDM) | - CREATE_SEPARATE_WOW_VDM; - } - } - - /* Get the path to the VDM host */ - Length = GetSystemDirectoryW(VdmPath, MAX_PATH - wcslen(NTVDM_STRING)); - if ((Length == 0) || (Length >= MAX_PATH - wcslen(NTVDM_STRING))) - { - /* System path not found for some reason, fail */ - SetLastError(ERROR_INVALID_NAME); - return FALSE; - } - wcscat(VdmPath, NTVDM_STRING); - - /* - * According to some sites, ShellExecuteEx uses an undocumented flag to - * send private handle data (such as HMONITOR or HICON). See: - * www.catch22.net/tuts/undoc01.asp. This implies that we can't use the - * standard handles anymore since we'd be overwriting this private data - */ + /* Check if private data is being sent on the same channel as std handles */ if ((StartupInfo.dwFlags & STARTF_USESTDHANDLES) && (StartupInfo.dwFlags & (STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))) { + /* Cannot use the std handles since we have monitor/hotkey values */ StartupInfo.dwFlags &= ~STARTF_USESTDHANDLES; } - /* Start by zeroing out the fields */ - RtlZeroMemory(lpProcessInformation, sizeof(PROCESS_INFORMATION)); - - /* Easy stuff first, convert the process priority class */ - PriorityClass.Foreground = FALSE; - PriorityClass.PriorityClass = (UCHAR)BasepConvertPriorityClass(dwCreationFlags); - - if (lpCommandLine) + /* If there's a debugger, or we have to launch cmd.exe, we go back here */ +AppNameRetry: + /* New iteration -- free any existing name buffer */ + if (NameBuffer) { - /* Search for escape sequences */ - ScanString = lpCommandLine; - while (NULL != (ScanString = wcschr(ScanString, L'^'))) - { - ScanString++; - if (*ScanString == L'\"' || *ScanString == L'^' || *ScanString == L'\\') - { - Escape = TRUE; - break; - } - } + RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); + NameBuffer = NULL; } - /* Get the application name and do all the proper formating necessary */ -GetAppName: - /* See if we have an application name (oh please let us have one!) */ + /* New iteration -- free any existing free buffer */ + if (FreeBuffer) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer); + FreeBuffer = NULL; + } + + /* New iteration -- close any existing file handle */ + if (FileHandle) + { + NtClose(FileHandle); + FileHandle = NULL; + } + + /* Set the initial parsing state. This code can loop -- don't move this! */ + ErrorCode = 0; + SearchRetry = TRUE; + QuotesNeeded = FALSE; + CmdLineIsAppName = FALSE; + + /* First check if we don't have an application name */ if (!lpApplicationName) { - /* The fun begins */ + /* This should be the first time we attempt creating one */ + ASSERT(NameBuffer == NULL); + + /* Allocate a buffer to hold it */ NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); - if (NameBuffer == NULL) + if (!NameBuffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Cleanup; + Result = FALSE; + goto Quickie; } - /* This is all we have to work with :( */ - lpApplicationName = lpCommandLine; + /* Initialize the application name and our parsing parameters */ + lpApplicationName = NullBuffer = ScanString = lpCommandLine; - /* Initialize our friends at the beginning */ - NullBuffer = (LPWSTR)lpApplicationName; - ScanString = (LPWSTR)lpApplicationName; - - /* We will start by looking for a quote */ - if (*ScanString == L'\"') + /* Check for an initial quote*/ + if (*lpCommandLine == L'\"') { - /* That was quick */ - SearchDone = TRUE; + /* We found a quote, keep searching for another one */ + SearchRetry = FALSE; + ScanString++; + lpApplicationName = ScanString; + while (*ScanString) + { + /* Have we found the terminating quote? */ + if (*ScanString == L'\"') + { + /* We're done, get out of here */ + NullBuffer = ScanString; + HasQuotes = TRUE; + break; + } - /* Advance past quote */ - ScanString++; - lpApplicationName = ScanString; - - /* Find the closing quote */ - while (*ScanString) - { - if (*ScanString == L'\"' && *(ScanString - 1) != L'^') - { - /* Found it */ - NullBuffer = ScanString; - FoundQuotes = TRUE; - break; - } - - /* Keep looking */ - ScanString++; - NullBuffer = ScanString; - } + /* Keep searching for the quote */ + ScanString++; + NullBuffer = ScanString; + } } else { - /* No quotes, so we'll be looking for white space */ - WhiteScan: - /* Reset the pointer */ +StartScan: + /* We simply make the application name be the command line*/ lpApplicationName = lpCommandLine; - - /* Find whitespace of Tab */ while (*ScanString) { - if (*ScanString == ' ' || *ScanString == '\t') + /* Check if it starts with a space or tab */ + if ((*ScanString == L' ') || (*ScanString == L'\t')) { - /* Found it */ + /* Break out of the search loop */ NullBuffer = ScanString; break; } - /* Keep looking */ + /* Keep searching for a space or tab */ ScanString++; NullBuffer = ScanString; } } - /* Set the Null Buffer */ + /* We have found the end of the application name, terminate it */ SaveChar = *NullBuffer; *NullBuffer = UNICODE_NULL; - /* Do a search for the file */ - DPRINT("Ready for SearchPathW: %S\n", lpApplicationName); - RetVal = SearchPathW(NULL, + /* New iteration -- free any existing saved path */ + if (SearchPath) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath); + SearchPath = NULL; + } + + /* Now compute the final EXE path based on the name */ + SearchPath = BaseComputeProcessExePath((LPWSTR)lpApplicationName); + DPRINT1("Search Path: %S\n", SearchPath); + if (!SearchPath) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + Result = FALSE; + goto Quickie; + } + + /* And search for the executable in the search path */ + Length = SearchPathW(SearchPath, lpApplicationName, L".exe", MAX_PATH, NameBuffer, - NULL) * sizeof(WCHAR); + NULL); - /* Did it find something? */ - if (RetVal) + /* Did we find it? */ + if ((Length) && (Length < MAX_PATH)) { /* Get file attributes */ - ULONG Attributes = GetFileAttributesW(NameBuffer); - if (Attributes & FILE_ATTRIBUTE_DIRECTORY) + CurdirLength = GetFileAttributesW(NameBuffer); + if ((CurdirLength != 0xFFFFFFFF) && + (CurdirLength & FILE_ATTRIBUTE_DIRECTORY)) { - /* Give it a length of 0 to fail, this was a directory. */ - RetVal = 0; + /* This was a directory, fail later on */ + Length = 0; } else { /* It's a file! */ - RetVal += sizeof(WCHAR); + Length++; } } - /* Now check if we have a file, and if the path size is OK */ - if (!RetVal || RetVal >= (MAX_PATH * sizeof(WCHAR))) + DPRINT1("Length: %lx Buffer: %S\n", Length, NameBuffer); + + /* Check if there was a failure in SearchPathW */ + if ((Length) && (Length < MAX_PATH)) { - ULONG PathType; - HANDLE hFile; - - /* We failed, try to get the Path Type */ - DPRINT("SearchPathW failed. Retval: %ld\n", RetVal); + /* Everything looks good, restore the name */ + *NullBuffer = SaveChar; + lpApplicationName = NameBuffer; + } + else + { + /* Check if this was a relative path, which would explain it */ PathType = RtlDetermineDosPathNameType_U(lpApplicationName); - - /* If it's not relative, try to get the error */ if (PathType != RtlPathTypeRelative) { /* This should fail, and give us a detailed LastError */ - hFile = CreateFileW(lpApplicationName, - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - /* Did it actually NOT fail? */ - if (hFile != INVALID_HANDLE_VALUE) + FileHandle = CreateFileW(lpApplicationName, + GENERIC_READ, + FILE_SHARE_READ | + FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (FileHandle != INVALID_HANDLE_VALUE) { - /* Fake the error */ - CloseHandle(hFile); + /* It worked? Return a generic error */ + CloseHandle(FileHandle); + FileHandle = NULL; BaseSetLastNTError(STATUS_OBJECT_NAME_NOT_FOUND); } } else { - /* Immediately set the error */ + /* Path was absolute, which means it doesn't exist */ BaseSetLastNTError(STATUS_OBJECT_NAME_NOT_FOUND); } /* Did we already fail once? */ - if (Error) + if (ErrorCode) { - SetLastError(Error); + /* Set the error code */ + SetLastError(ErrorCode); } else { /* Not yet, cache it */ - Error = GetLastError(); + ErrorCode = GetLastError(); } /* Put back the command line */ *NullBuffer = SaveChar; lpApplicationName = NameBuffer; - /* - * If the search isn't done and we still have cmdline - * then start over. Ex: c:\ha ha ha\haha.exe - */ - if (*ScanString && !SearchDone) + /* It's possible there's whitespace in the directory name */ + if (!(*ScanString) || !(SearchRetry)) { - /* Move in the buffer */ - ScanString++; - NullBuffer = ScanString; - - /* We will have to add a quote, since there is a space*/ - QuotesNeeded = TRUE; - - /* And we will also fake the fact we found one */ - FoundQuotes = TRUE; - - /* Start over */ - goto WhiteScan; + /* Not the case, give up completely */ + Result = FALSE; + goto Quickie; } - /* We totally failed */ - goto Cleanup; - } + /* There are spaces, so keep trying the next possibility */ + ScanString++; + NullBuffer = ScanString; - /* Put back the command line */ - *NullBuffer = SaveChar; - lpApplicationName = NameBuffer; - DPRINT("SearchPathW suceeded (%ld): %S\n", RetVal, NameBuffer); + /* We will have to add a quote, since there is a space */ + QuotesNeeded = TRUE; + HasQuotes = TRUE; + goto StartScan; + } } - else if (!lpCommandLine || *lpCommandLine == UNICODE_NULL) + else if (!(lpCommandLine) || !(*lpCommandLine)) { - /* We have an app name (good!) but no command line */ + /* We don't have a command line, so just use the application name */ CmdLineIsAppName = TRUE; lpCommandLine = (LPWSTR)lpApplicationName; } - /* At this point the name has been toyed with enough to be openable */ - Status = BasepMapFile(lpApplicationName, &hSection, &ApplicationName); + /* Convert the application name to its NT path */ + TranslationStatus = RtlDosPathNameToRelativeNtPathName_U(lpApplicationName, + &PathName, + NULL, + &SxsWin32RelativePath); + if (!TranslationStatus) + { + /* Path must be invaild somehow, bail out */ + DPRINT1("Path translation for SxS failed\n"); + SetLastError(ERROR_PATH_NOT_FOUND); + Result = FALSE; + goto Quickie; + } - /* Check for failure */ + /* Setup the buffer that needs to be freed at the end */ + ASSERT(FreeBuffer == NULL); + FreeBuffer = PathName.Buffer; + + /* Check what kind of path the application is, for SxS (Fusion) purposes */ + RtlInitUnicodeString(&SxsWin32ExePath, lpApplicationName); + SxsPathType = RtlDetermineDosPathNameType_U(lpApplicationName); + if ((SxsPathType != RtlPathTypeDriveAbsolute) && + (SxsPathType != RtlPathTypeLocalDevice) && + (SxsPathType != RtlPathTypeRootLocalDevice) && + (SxsPathType != RtlPathTypeUncAbsolute)) + { + /* Relative-type path, get the full path */ + RtlInitEmptyUnicodeString(&PathBufferString, NULL, 0); + Status = RtlGetFullPathName_UstrEx(&SxsWin32ExePath, + NULL, + &PathBufferString, + NULL, + NULL, + NULL, + &SxsPathType, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Fail the rest of the create */ + RtlReleaseRelativeName(&SxsWin32RelativePath); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* Use this full path as the SxS path */ + SxsWin32ExePath = PathBufferString; + PathBuffer = PathBufferString.Buffer; + PathBufferString.Buffer = NULL; + DPRINT1("SxS Path: %S\n", PathBuffer); + } + + /* Also set the .EXE path based on the path name */ +#if _SXS_SUPPORT_ENABLED_ + SxsNtExePath = PathName; +#endif + if (SxsWin32RelativePath.RelativeName.Length) + { + /* If it's relative, capture the relative name */ + PathName = SxsWin32RelativePath.RelativeName; + } + else + { + /* Otherwise, it's absolute, make sure no relative dir is used */ + SxsWin32RelativePath.ContainingDirectory = NULL; + } + + /* Now use the path name, and the root path, to try opening the app */ + DPRINT1("Path: %wZ. Dir: %lx\n", &PathName, SxsWin32RelativePath.ContainingDirectory); + InitializeObjectAttributes(&LocalObjectAttributes, + &PathName, + OBJ_CASE_INSENSITIVE, + SxsWin32RelativePath.ContainingDirectory, + NULL); + Status = NtOpenFile(&FileHandle, + SYNCHRONIZE | + FILE_READ_ATTRIBUTES | + FILE_READ_DATA | + FILE_EXECUTE, + &LocalObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_DELETE, + FILE_SYNCHRONOUS_IO_NONALERT | + FILE_NON_DIRECTORY_FILE); if (!NT_SUCCESS(Status)) { - /* Could be a non-PE File */ - switch (Status) + /* Try to open the app just for execute purposes instead */ + Status = NtOpenFile(&FileHandle, + SYNCHRONIZE | FILE_EXECUTE, + &LocalObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_DELETE, + FILE_SYNCHRONOUS_IO_NONALERT | + FILE_NON_DIRECTORY_FILE); + } + + /* Cleanup in preparation for failure or success */ + RtlReleaseRelativeName(&SxsWin32RelativePath); + if (!NT_SUCCESS(Status)) + { + /* Failure path, try to understand why */ + DPRINT1("Open file failed: %lx\n", Status); + if (RtlIsDosDeviceName_U(lpApplicationName)) { - /* Check if the Kernel tells us it's not even valid MZ */ - case STATUS_INVALID_IMAGE_NE_FORMAT: - case STATUS_INVALID_IMAGE_PROTECT: - case STATUS_INVALID_IMAGE_NOT_MZ: - - /* If it's a DOS app, use VDM */ - if (BaseIsDosApplication(&ApplicationName, Status)) - { - DPRINT1("Launching VDM...\n"); - RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); - RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer); - return CreateProcessW(VdmPath, - (LPWSTR)((ULONG_PTR)lpApplicationName), /* FIXME: Buffer must be writable!!! */ - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - lpEnvironment, - lpCurrentDirectory, - &StartupInfo, - lpProcessInformation); - } - /* It's a batch file */ - Extension = &ApplicationName.Buffer[ApplicationName.Length / - sizeof(WCHAR) - 4]; - - /* Make sure the extensions are correct */ - if (_wcsnicmp(Extension, L".bat", 4) && _wcsnicmp(Extension, L".cmd", 4)) - { - SetLastError(ERROR_BAD_EXE_FORMAT); - return FALSE; - } - - /* Calculate the length of the command line */ - CmdLineLength = wcslen(CMD_STRING) + wcslen(lpCommandLine) + 1; - - /* If we found quotes, then add them into the length size */ - if (CmdLineIsAppName || FoundQuotes) CmdLineLength += 2; - CmdLineLength *= sizeof(WCHAR); - - /* Allocate space for the new command line */ - BatchCommandLine = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - CmdLineLength); - if (BatchCommandLine == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Cleanup; - } - - /* Build it */ - wcscpy(BatchCommandLine, CMD_STRING); - if (CmdLineIsAppName || FoundQuotes) - { - wcscat(BatchCommandLine, L"\""); - } - wcscat(BatchCommandLine, lpCommandLine); - if (CmdLineIsAppName || FoundQuotes) - { - wcscat(BatchCommandLine, L"\""); - } - - /* Create it as a Unicode String */ - RtlInitUnicodeString(&CommandLineString, BatchCommandLine); - - /* Set the command line to this */ - lpCommandLine = CommandLineString.Buffer; - lpApplicationName = NULL; - - /* Free memory */ - RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer); - ApplicationName.Buffer = NULL; - goto GetAppName; - break; - - case STATUS_INVALID_IMAGE_WIN_16: - - /* It's a Win16 Image, use VDM */ - DPRINT1("Launching VDM...\n"); - RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); - RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer); - return CreateProcessW(VdmPath, - (LPWSTR)((ULONG_PTR)lpApplicationName), /* FIXME: Buffer must be writable!!! */ - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - lpEnvironment, - lpCurrentDirectory, - &StartupInfo, - lpProcessInformation); - - case STATUS_OBJECT_NAME_NOT_FOUND: - case STATUS_OBJECT_PATH_NOT_FOUND: - BaseSetLastNTError(Status); - goto Cleanup; - - default: - /* Invalid Image Type */ - SetLastError(ERROR_BAD_EXE_FORMAT); - goto Cleanup; + /* If a device is being executed, return this special error code */ + SetLastError(ERROR_BAD_DEVICE); + Result = FALSE; + goto Quickie; + } + else + { + /* Otherwise return the converted NT error code */ + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; } } - /* Use our desktop if we didn't get any */ + /* Did the caller specify a desktop? */ if (!StartupInfo.lpDesktop) { - StartupInfo.lpDesktop = OurPeb->ProcessParameters->DesktopInfo.Buffer; + /* Use the one from the current process */ + StartupInfo.lpDesktop = Peb->ProcessParameters->DesktopInfo.Buffer; } - /* FIXME: Check if Application is allowed to run */ - - /* FIXME: Allow CREATE_SEPARATE only for WOW Apps, once we have that. */ - - /* Get some information about the executable */ - Status = NtQuerySection(hSection, - SectionImageInformation, - &SectionImageInfo, - sizeof(SectionImageInfo), - NULL); - if(!NT_SUCCESS(Status)) + /* Create a section for this file */ + Status = NtCreateSection(&SectionHandle, + SECTION_ALL_ACCESS, + NULL, + NULL, + PAGE_EXECUTE, + SEC_IMAGE, + FileHandle); + DPRINT1("Section status: %lx\n", Status); + if (NT_SUCCESS(Status)) { - DPRINT1("Unable to get SectionImageInformation, status 0x%x\n", Status); - BaseSetLastNTError(Status); - goto Cleanup; + /* Are we running on Windows Embedded, Datacenter, Blade or Starter? */ + if (SharedUserData->SuiteMask & (VER_SUITE_EMBEDDEDNT | + VER_SUITE_DATACENTER | + VER_SUITE_PERSONAL | + VER_SUITE_BLADE)) + { + /* These SKUs do not allow running certain applications */ + Status = BasepCheckWebBladeHashes(FileHandle); + if (Status == STATUS_ACCESS_DENIED) + { + /* And this is one of them! */ + DPRINT1("Invalid Blade hashes!\n"); + SetLastError(ERROR_ACCESS_DISABLED_WEBBLADE); + Result = FALSE; + goto Quickie; + } + + /* Did we get some other failure? */ + if (!NT_SUCCESS(Status)) + { + /* If we couldn't check the hashes, assume nefariousness */ + DPRINT1("Tampered Blade hashes!\n"); + SetLastError(ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER); + Result = FALSE; + goto Quickie; + } + } + + /* Now do Winsafer, etc, checks */ + Status = BasepIsProcessAllowed((LPWSTR)lpApplicationName); + if (!NT_SUCCESS(Status)) + { + /* Fail if we're not allowed to launch the process */ + DPRINT1("Process not allowed to launch: %lx\n", Status); + BaseSetLastNTError(Status); + if (SectionHandle) + { + NtClose(SectionHandle); + SectionHandle = NULL; + } + Result = FALSE; + goto Quickie; + } + + /* Is a DOS VDM being forced, but we already have a WOW32 instance ready? */ + if ((dwCreationFlags & CREATE_FORCEDOS) && + (BaseStaticServerData->IsWowTaskReady)) + { + /* This request can't be satisfied, instead, a separate VDM is needed */ + dwCreationFlags &= ~(CREATE_FORCEDOS | CREATE_SHARED_WOW_VDM); + dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; + + /* Set a failure code, ask for VDM reservation */ + Status = STATUS_INVALID_IMAGE_WIN_16; + UseVdmReserve = TRUE; + + /* Close the current handle */ + NtClose(SectionHandle); + SectionHandle = NULL; + + /* Don't query the section later */ + QuerySection = FALSE; + } } - /* Don't execute DLLs */ - if (SectionImageInfo.ImageCharacteristics & IMAGE_FILE_DLL) + /* Did we already do these checks? */ + if (!SkipSaferAndAppCompat) { - DPRINT1("Can't execute a DLL\n"); + /* Is everything OK so far, OR do we have an non-MZ, non-DOS app? */ + if ((NT_SUCCESS(Status)) || + ((Status == STATUS_INVALID_IMAGE_NOT_MZ) && + !(BaseIsDosApplication(&PathName, Status)))) + { + /* Clear the machine type in case of failure */ + ImageMachine = 0; + + /* Clean any app compat data that may have accumulated */ + BasepFreeAppCompatData(AppCompatData, AppCompatSxsData); + AppCompatData = NULL; + AppCompatSxsData = NULL; + + /* Do we have a section? */ + if (SectionHandle) + { + /* Have we already queried it? */ + if (QuerySection) + { + /* Nothing to do */ + Status = STATUS_SUCCESS; + } + else + { + /* Get some information about the executable */ + Status = NtQuerySection(SectionHandle, + SectionImageInformation, + &ImageInformation, + sizeof(ImageInformation), + NULL); + } + + /* Do we have section information now? */ + if (NT_SUCCESS(Status)) + { + /* Don't ask for it again, save the machine type */ + QuerySection = TRUE; + ImageMachine = ImageInformation.Machine; + } + } + + /* Is there a reason/Shim we shouldn't run this application? */ + Status = BasepCheckBadapp(FileHandle, + FreeBuffer, + lpEnvironment, + ImageMachine, + &AppCompatData, + &AppCompatDataSize, + &AppCompatSxsData, + &AppCompatSxsDataSize, + &FusionFlags); + if (!NT_SUCCESS(Status)) + { + /* This is usually the status we get back */ + DPRINT1("App compat launch failure: %lx\n", Status); + if (Status == STATUS_ACCESS_DENIED) + { + /* Convert it to something more Win32-specific */ + SetLastError(ERROR_CANCELLED); + } + else + { + /* Some other error */ + BaseSetLastNTError(Status); + } + + /* Did we have a section? */ + if (SectionHandle) + { + /* Clean it up */ + NtClose(SectionHandle); + SectionHandle = NULL; + } + + /* Fail the call */ + Result = FALSE; + goto Quickie; + } + } + } + + //ASSERT((dwFusionFlags & ~SXS_APPCOMPACT_FLAG_APP_RUNNING_SAFEMODE) == 0); + + /* Have we already done, and do we need to do, SRP (WinSafer) checks? */ + if (!(SkipSaferAndAppCompat) && + ~(dwCreationFlags & CREATE_PRESERVE_CODE_AUTHZ_LEVEL)) + { + /* Assume yes */ + SaferNeeded = TRUE; + switch (Status) + { + case STATUS_INVALID_IMAGE_NE_FORMAT: + case STATUS_INVALID_IMAGE_PROTECT: + case STATUS_INVALID_IMAGE_WIN_16: + case STATUS_FILE_IS_OFFLINE: + /* For all DOS, 16-bit, OS/2 images, we do*/ + break; + + case STATUS_INVALID_IMAGE_NOT_MZ: + /* For invalid files, we don't, unless it's a .BAT file */ + if (BaseIsDosApplication(&PathName, Status)) break; + + default: + /* Any other error codes we also don't */ + if (!NT_SUCCESS(Status)) + { + SaferNeeded = FALSE; + } + + /* But for success, we do */ + break; + } + + /* Okay, so what did the checks above result in? */ + if (SaferNeeded) + { + /* We have to call into the WinSafer library and actually check */ + Status = BasepCheckWinSaferRestrictions(hUserToken, + (LPWSTR)lpApplicationName, + FileHandle, + &InJob, + &TokenHandle, + &JobHandle); + if (Status == 0xFFFFFFFF) + { + /* Back in 2003, they didn't have an NTSTATUS for this... */ + DPRINT1("WinSafer blocking process launch\n"); + SetLastError(ERROR_ACCESS_DISABLED_BY_POLICY); + Result = FALSE; + goto Quickie; + } + + /* Other status codes are not-Safer related, just convert them */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error checking WinSafer: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + } + } + + /* The last step is to figure out why the section object was not created */ + switch (Status) + { + case STATUS_INVALID_IMAGE_WIN_16: + /* 16-bit binary. Should we use WOW or does the caller force VDM? */ + if (!(dwCreationFlags & CREATE_FORCEDOS)) + { + /* Remember that we're launching WOW */ + IsWowApp = TRUE; + + /* Create the VDM environment, it's valid for WOW too */ + Result = BaseCreateVDMEnvironment(lpEnvironment, + &VdmAnsiEnv, + &VdmUnicodeEnv); + if (!Result) + { + DPRINT1("VDM environment for WOW app failed\n"); + goto Quickie; + } + + /* We're going to try this twice, so do a loop */ + while (TRUE) + { + /* Pick which kind of WOW mode we want to run in */ + VdmBinaryType = (dwCreationFlags & + CREATE_SEPARATE_WOW_VDM) ? + BINARY_TYPE_WOW : BINARY_TYPE_SEPARATE_WOW; + + /* Get all the VDM settings and current status */ + Status = BaseCheckVDM(VdmBinaryType, + lpApplicationName, + lpCommandLine, + lpCurrentDirectory, + &VdmAnsiEnv, + (PCSR_API_MESSAGE)VdmMsg, + &VdmTask, + dwCreationFlags, + &StartupInfo, + hUserToken); + + /* If it worked, no need to try again */ + if (NT_SUCCESS(Status)) break; + + /* Check if it's disallowed or if it's our second time */ + BaseSetLastNTError(Status); + if ((Status == STATUS_VDM_DISALLOWED) || + (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW) || + (GetLastError() == ERROR_ACCESS_DENIED)) + { + /* Fail the call -- we won't try again */ + DPRINT1("VDM message failure for WOW: %lx\n", Status); + Result = FALSE; + goto Quickie; + } + + /* Try one more time, but with a separate WOW instance */ + dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; + } + + /* Check which VDM state we're currently in */ + switch (VdmMsg->VDMState & (VDM_NOT_LOADED | + VDM_NOT_READY | + VDM_READY)) + { + case VDM_NOT_LOADED: + /* VDM is not fully loaded, so not that much to undo */ + VdmUndoLevel = VDM_UNDO_PARTIAL; + + /* Reset VDM reserve if needed */ + if (UseVdmReserve) VdmReserve = 1; + + /* Get the required parameters and names for launch */ + Result = BaseGetVdmConfigInfo(lpCommandLine, + VdmTask, + VdmBinaryType, + &VdmString, + &VdmReserve); + if (!Result) + { + DPRINT1("VDM Configuration failed for WOW\n"); + BaseSetLastNTError(Status); + goto Quickie; + } + + /* Update the command-line with the VDM one instead */ + lpCommandLine = VdmString.Buffer; + lpApplicationName = NULL; + + /* We don't want a console, detachment, nor a window */ + dwCreationFlags |= CREATE_NO_WINDOW; + dwCreationFlags &= ~(CREATE_NEW_CONSOLE | DETACHED_PROCESS); + + /* Force feedback on */ + StartupInfo.dwFlags |= STARTF_FORCEONFEEDBACK; + break; + + + case VDM_READY: + /* VDM is ready, so we have to undo everything */ + VdmUndoLevel = VDM_UNDO_REUSE; + + /* Check if CSRSS wants us to wait on VDM */ + VdmWaitObject = VdmMsg->WaitObjectForParent; + break; + + case VDM_NOT_READY: + /* Something is wrong with VDM, we'll fail the call */ + DPRINT1("VDM is not ready for WOW\n"); + SetLastError(ERROR_NOT_READY); + Result = FALSE; + goto Quickie; + + default: + break; + } + + /* Since to get NULL, we allocate from 0x1, account for this */ + VdmReserve--; + + /* This implies VDM is ready, so skip everything else */ + if (VdmWaitObject) goto VdmShortCircuit; + + /* Don't inherit handles since we're doing VDM now */ + bInheritHandles = FALSE; + + /* Had the user passed in environment? If so, destroy it */ + if ((lpEnvironment) && + !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + { + RtlDestroyEnvironment(lpEnvironment); + } + + /* We've already done all these checks, don't do them again */ + SkipSaferAndAppCompat = TRUE; + goto AppNameRetry; + } + + // There is no break here on purpose, so FORCEDOS drops down! + case STATUS_INVALID_IMAGE_PROTECT: + case STATUS_INVALID_IMAGE_NOT_MZ: + case STATUS_INVALID_IMAGE_NE_FORMAT: + /* We're launching an executable application */ + BinarySubType = BINARY_TYPE_EXE; + + /* We can drop here from other "cases" above too, so check */ + if ((Status == STATUS_INVALID_IMAGE_PROTECT) || + (Status == STATUS_INVALID_IMAGE_NE_FORMAT) || + (BinarySubType = BaseIsDosApplication(&PathName, Status))) + { + /* We're launching a DOS application */ + VdmBinaryType = BINARY_TYPE_DOS; + + /* Based on the caller environment, create a VDM one */ + Result = BaseCreateVDMEnvironment(lpEnvironment, + &VdmAnsiEnv, + &VdmUnicodeEnv); + if (!Result) + { + DPRINT1("VDM environment for DOS failed\n"); + goto Quickie; + } + + /* Check the current state of the VDM subsystem */ + Status = BaseCheckVDM(VdmBinaryType | BinarySubType, + lpApplicationName, + lpCommandLine, + lpCurrentDirectory, + &VdmAnsiEnv, + (PCSR_API_MESSAGE)VdmMsg, + &VdmTask, + dwCreationFlags, + &StartupInfo, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Failed to inquire about VDM, fail the call */ + DPRINT1("VDM message failure for DOS: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + }; + + /* Handle possible VDM states */ + switch (VdmMsg->VDMState & (VDM_NOT_LOADED | + VDM_NOT_READY | + VDM_READY)) + { + case VDM_NOT_LOADED: + /* If VDM is not loaded, we'll do a partial undo */ + VdmUndoLevel = VDM_UNDO_PARTIAL; + + /* A VDM process can't also be detached, so fail */ + if (dwCreationFlags & DETACHED_PROCESS) + { + DPRINT1("Detached process but no VDM, not allowed\n"); + SetLastError(ERROR_ACCESS_DENIED); + return FALSE; + } + + /* Get the required parameters and names for launch */ + Result = BaseGetVdmConfigInfo(lpCommandLine, + VdmTask, + VdmBinaryType, + &VdmString, + &VdmReserve); + if (!Result) + { + DPRINT1("VDM Configuration failed for DOS\n"); + BaseSetLastNTError(Status); + goto Quickie; + } + + /* Update the command-line to launch VDM instead */ + lpCommandLine = VdmString.Buffer; + lpApplicationName = NULL; + break; + + case VDM_READY: + /* VDM is ready, so we have to undo everything */ + VdmUndoLevel = VDM_UNDO_REUSE; + + /* Check if CSRSS wants us to wait on VDM */ + VdmWaitObject = VdmMsg->WaitObjectForParent; + break; + + case VDM_NOT_READY: + /* Something is wrong with VDM, we'll fail the call */ + DPRINT1("VDM is not ready for DOS\n"); + SetLastError(ERROR_NOT_READY); + Result = FALSE; + goto Quickie; + + default: + break; + } + + /* Since to get NULL, we allocate from 0x1, account for this */ + VdmReserve--; + + /* This implies VDM is ready, so skip everything else */ + if (VdmWaitObject) goto VdmShortCircuit; + + /* Don't inherit handles since we're doing VDM now */ + bInheritHandles = FALSE; + + /* Had the user passed in environment? If so, destroy it */ + if ((lpEnvironment) && + !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + { + RtlDestroyEnvironment(lpEnvironment); + } + + /* Use our VDM Unicode environment instead */ + lpEnvironment = VdmUnicodeEnv.Buffer; + } + else + { + /* It's a batch file, get the extension */ + ExtBuffer = &PathName.Buffer[PathName.Length / sizeof(WCHAR) - 4]; + + /* Make sure the extensions are correct */ + if ((PathName.Length < (4 * sizeof(WCHAR))) || + ((_wcsnicmp(ExtBuffer, L".bat", 4)) && + (_wcsnicmp(ExtBuffer, L".cmd", 4)))) + { + DPRINT1("Invalid EXE, and not a batch or script file\n"); + SetLastError(ERROR_BAD_EXE_FORMAT); + Result = FALSE; + goto Quickie; + } + + /* Check if we need to account for quotes around the path */ + CmdQuoteLength = CmdLineIsAppName || HasQuotes; + if (!CmdLineIsAppName) + { + if (HasQuotes) CmdQuoteLength++; + } + else + { + CmdQuoteLength++; + } + + /* Calculate the length of the command line */ + CmdLineLength = wcslen(lpCommandLine); + CmdLineLength += wcslen(CMD_STRING); + CmdLineLength += CmdQuoteLength + sizeof(ANSI_NULL); + CmdLineLength *= sizeof(WCHAR); + + /* Allocate space for the new command line */ + AnsiCmdCommand = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + CmdLineLength); + if (!AnsiCmdCommand) + { + BaseSetLastNTError(STATUS_NO_MEMORY); + Result = FALSE; + goto Quickie; + } + + /* Build it */ + wcscpy(AnsiCmdCommand, CMD_STRING); + if ((CmdLineIsAppName) || (HasQuotes)) + { + wcscat(AnsiCmdCommand, L"\""); + } + wcscat(AnsiCmdCommand, lpCommandLine); + if ((CmdLineIsAppName) || (HasQuotes)) + { + wcscat(AnsiCmdCommand, L"\""); + } + + /* Create it as a Unicode String */ + RtlInitUnicodeString(&DebuggerString, AnsiCmdCommand); + + /* Set the command line to this */ + lpCommandLine = DebuggerString.Buffer; + lpApplicationName = NULL; + DPRINT1("Retrying with: %S\n", lpCommandLine); + } + + /* We've already done all these checks, don't do them again */ + SkipSaferAndAppCompat = TRUE; + goto AppNameRetry; + + case STATUS_INVALID_IMAGE_WIN_64: + /* 64-bit binaries are not allowed to run on 32-bit ReactOS */ + DPRINT1("64-bit binary, failing\n"); + SetLastError(ERROR_EXE_MACHINE_TYPE_MISMATCH); + Result = FALSE; + goto Quickie; + + case STATUS_FILE_IS_OFFLINE: + /* Set the correct last error for this */ + DPRINT1("File is offline, failing\n"); + SetLastError(ERROR_FILE_OFFLINE); + break; + + default: + /* Any other error, convert it to a generic Win32 error */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create section: %lx\n", Status); + SetLastError(ERROR_BAD_EXE_FORMAT); + Result = FALSE; + goto Quickie; + } + + /* Otherwise, this must be success */ + ASSERT(Status == STATUS_SUCCESS); + break; + } + + /* Is this not a WOW application, but a WOW32 VDM was requested for it? */ + if (!(IsWowApp) && (dwCreationFlags & CREATE_SEPARATE_WOW_VDM)) + { + /* Ignore the nonsensical request */ + dwCreationFlags &= ~CREATE_SEPARATE_WOW_VDM; + } + + /* Did we already check information for the section? */ + if (!QuerySection) + { + /* Get some information about the executable */ + Status = NtQuerySection(SectionHandle, + SectionImageInformation, + &ImageInformation, + sizeof(ImageInformation), + NULL); + if (!NT_SUCCESS(Status)) + { + /* We failed, bail out */ + DPRINT1("Section query failed\n"); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* Don't check this later */ + QuerySection = TRUE; + } + + /* Check if this was linked as a DLL */ + if (ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL) + { + /* These aren't valid images to try to execute! */ + DPRINT1("Trying to launch a DLL, failing\n"); SetLastError(ERROR_BAD_EXE_FORMAT); - goto Cleanup; + Result = FALSE; + goto Quickie; } - /* FIXME: Check for Debugger */ + /* Don't let callers pass in this flag -- we'll only get it from IFRO */ + Flags &= ~PROCESS_CREATE_FLAGS_LARGE_PAGES; - /* FIXME: Check if Machine Type and SubSys Version Match */ + /* Clear the IFEO-missing flag, before we know for sure... */ + ParameterFlags &= ~2; - /* We don't support POSIX or anything else for now */ - if (IMAGE_SUBSYSTEM_WINDOWS_GUI != SectionImageInfo.SubSystemType && - IMAGE_SUBSYSTEM_WINDOWS_CUI != SectionImageInfo.SubSystemType) + /* If the process is being debugged, only read IFEO if the PEB says so */ + if (!(dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) || + (NtCurrentPeb()->ReadImageFileExecOptions)) { - DPRINT1("Invalid subsystem %d\n", SectionImageInfo.SubSystemType); - /* - * Despite the name of the error code suggests, it corresponds to the - * well-known "The %1 application cannot be run in Win32 mode" message. - */ - SetLastError(ERROR_CHILD_NOT_COMPLETE); - goto Cleanup; + /* Let's do this! Attempt to open IFEO */ + Status1 = LdrOpenImageFileOptionsKey(&PathName, 0, &KeyHandle); + if (!NT_SUCCESS(Status1)) + { + /* We failed, set the flag so we store this in the parameters */ + if (Status1 == STATUS_OBJECT_NAME_NOT_FOUND) ParameterFlags |= 2; + } + else + { + /* Was this our first time going through this path? */ + if (!DebuggerCmdLine) + { + /* Allocate a buffer for the debugger path */ + DebuggerCmdLine = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + MAX_PATH * sizeof(WCHAR)); + if (!DebuggerCmdLine) + { + /* Close IFEO on failure */ + Status1 = NtClose(KeyHandle); + ASSERT(NT_SUCCESS(Status1)); + + /* Fail the call */ + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + Result = FALSE; + goto Quickie; + } + } + + /* Now query for the debugger */ + Status1 = LdrQueryImageFileKeyOption(KeyHandle, + L"Debugger", + REG_SZ, + DebuggerCmdLine, + MAX_PATH * sizeof(WCHAR), + &ResultSize); + if (!(NT_SUCCESS(Status1)) || + (ResultSize < sizeof(WCHAR)) || + (DebuggerCmdLine[0] == UNICODE_NULL)) + { + /* If it's not there, or too small, or invalid, ignore it */ + RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine); + DebuggerCmdLine = NULL; + } + + /* Also query if we should map with large pages */ + Status1 = LdrQueryImageFileKeyOption(KeyHandle, + L"UseLargePages", + REG_DWORD, + &UseLargePages, + sizeof(UseLargePages), + NULL); + if ((NT_SUCCESS(Status1)) && (UseLargePages)) + { + /* Do it! This is the only way this flag can be set */ + Flags |= PROCESS_CREATE_FLAGS_LARGE_PAGES; + } + + /* We're done with IFEO, can close it now */ + Status1 = NtClose(KeyHandle); + ASSERT(NT_SUCCESS(Status1)); + } } - if (IMAGE_SUBSYSTEM_WINDOWS_GUI == SectionImageInfo.SubSystemType) + /* Make sure the image was compiled for this processor */ + if ((ImageInformation.Machine < SharedUserData->ImageNumberLow) || + (ImageInformation.Machine > SharedUserData->ImageNumberHigh)) { - /* Do not create a console for GUI applications */ - dwCreationFlags &= ~CREATE_NEW_CONSOLE; - dwCreationFlags |= DETACHED_PROCESS; + /* It was not -- raise a hard error */ + ErrorResponse = ResponseOk; + ErrorParameters[0] = (ULONG_PTR)&PathName; + NtRaiseHardError(STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE, + 1, + 1, + ErrorParameters, + OptionOk, + &ErrorResponse); + if (Peb->ImageSubsystemMajorVersion <= 3) + { + /* If it's really old, return this error */ + SetLastError(ERROR_BAD_EXE_FORMAT); + } + else + { + /* Otherwise, return a more modern error */ + SetLastError(ERROR_EXE_MACHINE_TYPE_MISMATCH); + } + + /* Go to the failure path */ + DPRINT1("Invalid image architecture: %lx\n", ImageInformation.Machine); + Result = FALSE; + goto Quickie; + } + + /* Check if this isn't a Windows image */ + if ((ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_GUI) && + (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_CUI)) + { + /* Get rid of section-related information since we'll retry */ + NtClose(SectionHandle); + SectionHandle = NULL; + QuerySection = FALSE; + + /* The only other non-Windows image type we support here is POSIX */ + if (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_POSIX_CUI) + { + /* Bail out if it's something else */ + SetLastError(ERROR_CHILD_NOT_COMPLETE); + Result = FALSE; + goto Quickie; + } + + /* Now build the command-line to have posix launch this image */ + Result = BuildSubSysCommandLine(L"POSIX /P ", + lpApplicationName, + lpCommandLine, + &DebuggerString); + if (!Result) + { + /* Bail out if that failed */ + DPRINT1("Subsystem command line failed\n"); + goto Quickie; + } + + /* And re-try launching the process, with the new command-line now */ + lpCommandLine = DebuggerString.Buffer; + lpApplicationName = NULL; + + /* We've already done all these checks, don't do them again */ + SkipSaferAndAppCompat = TRUE; + DPRINT1("Retrying with: %S\n", lpCommandLine); + goto AppNameRetry; + } + + /* Was this image built for a version of Windows whose images we can run? */ + Result = BasepIsImageVersionOk(ImageInformation.SubSystemMajorVersion, + ImageInformation.SubSystemMinorVersion); + if (!Result) + { + /* It was not, bail out */ + DPRINT1("Invalid subsystem version: %d.%d\n", + ImageInformation.SubSystemMajorVersion, + ImageInformation.SubSystemMinorVersion); + SetLastError(ERROR_BAD_EXE_FORMAT); + goto Quickie; + } + + /* Check if there is a debugger associated with the application */ + if (DebuggerCmdLine) + { + /* Get the length of the command line */ + n = wcslen(lpCommandLine); + if (!n) + { + /* There's no command line, use the application name instead */ + lpCommandLine = (LPWSTR)lpApplicationName; + n = wcslen(lpCommandLine); + } + + /* Protect against overflow */ + if (n > UNICODE_STRING_MAX_CHARS) + { + BaseSetLastNTError(STATUS_NAME_TOO_LONG); + Result = FALSE; + goto Quickie; + } + + /* Now add the length of the debugger command-line */ + n += wcslen(DebuggerCmdLine); + + /* Again make sure we don't overflow */ + if (n > UNICODE_STRING_MAX_CHARS) + { + BaseSetLastNTError(STATUS_NAME_TOO_LONG); + Result = FALSE; + goto Quickie; + } + + /* Account for the quotes and space between the two */ + n += ((sizeof('""') * 2) + sizeof(' ')); + + /* Convert to bytes, and make sure we don't overflow */ + n *= sizeof(WCHAR); + if (n > UNICODE_STRING_MAX_BYTES) + { + BaseSetLastNTError(STATUS_NAME_TOO_LONG); + Result = FALSE; + goto Quickie; + } + + /* Allocate space for the string */ + DebuggerString.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, n); + if (!DebuggerString.Buffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + Result = FALSE; + goto Quickie; + } + + /* Set the length */ + RtlInitEmptyUnicodeString(&DebuggerString, + DebuggerString.Buffer, + n); + + /* Now perform the command line creation */ + ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, + DebuggerCmdLine); + ASSERT(NT_SUCCESS(ImageDbgStatus)); + ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, L" "); + ASSERT(NT_SUCCESS(ImageDbgStatus)); + ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, lpCommandLine); + ASSERT(NT_SUCCESS(ImageDbgStatus)); + + /* Make sure it all looks nice */ + DbgPrint("BASE: Calling debugger with '%wZ'\n", &DebuggerString); + + /* Update the command line and application name */ + lpCommandLine = DebuggerString.Buffer; + lpApplicationName = NULL; + + /* Close all temporary state */ + NtClose(SectionHandle); + SectionHandle = NULL; + QuerySection = FALSE; + + /* Free all temporary memory */ + RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); + NameBuffer = NULL; + RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer); + FreeBuffer = NULL; + RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine); + DebuggerCmdLine = NULL; + DPRINT1("Retrying with: %S\n", lpCommandLine); + goto AppNameRetry; } /* Initialize the process object attributes */ ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, - lpProcessAttributes, - NULL); + lpProcessAttributes, + NULL); + if ((hUserToken) && (lpProcessAttributes)) + { + /* Auggment them with information from the user */ + + LocalProcessAttributes = *lpProcessAttributes; + LocalProcessAttributes.lpSecurityDescriptor = NULL; + ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, + &LocalProcessAttributes, + NULL); + } /* Check if we're going to be debugged */ if (dwCreationFlags & DEBUG_PROCESS) { - /* FIXME: Set process flag */ + /* Set process flag */ + Flags |= PROCESS_CREATE_FLAGS_BREAKAWAY; } /* Check if we're going to be debugged */ @@ -3034,275 +3834,755 @@ GetAppName: { DPRINT1("Failed to connect to DbgUI!\n"); BaseSetLastNTError(Status); - goto Cleanup; + Result = FALSE; + goto Quickie; } /* Get the debug object */ - hDebug = DbgUiGetThreadDebugObject(); + DebugHandle = DbgUiGetThreadDebugObject(); /* Check if only this process will be debugged */ if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS) { /* Set process flag */ - hDebug = (HANDLE)((ULONG_PTR)hDebug | 0x1); + Flags |= PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT; } } - /* Create the Process */ - Status = NtCreateProcess(&hProcess, - PROCESS_ALL_ACCESS, - ObjectAttributes, - NtCurrentProcess(), - (BOOLEAN)bInheritHandles, - hSection, - hDebug, - NULL); - if (!NT_SUCCESS(Status)) + /* Set inherit flag */ + if (bInheritHandles) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES; + + /* Check if the process should be created with large pages */ + HavePrivilege = FALSE; + PrivilegeState = NULL; + if (Flags & PROCESS_CREATE_FLAGS_LARGE_PAGES) { - DPRINT1("Unable to create process, status 0x%x\n", Status); - BaseSetLastNTError(Status); - goto Cleanup; + /* Acquire the required privilege so that the kernel won't fail the call */ + PrivilegeValue = SE_LOCK_MEMORY_PRIVILEGE; + Status = RtlAcquirePrivilege(&PrivilegeValue, TRUE, FALSE, &PrivilegeState); + if (NT_SUCCESS(Status)) + { + /* Remember to release it later */ + HavePrivilege = TRUE; + } } - if (PriorityClass.PriorityClass != PROCESS_PRIORITY_CLASS_INVALID) + /* Save the current TIB value since kernel overwrites it to store PEB */ + TibValue = Teb->NtTib.ArbitraryUserPointer; + + /* Tell the kernel to create the process */ + Status = NtCreateProcessEx(&ProcessHandle, + PROCESS_ALL_ACCESS, + ObjectAttributes, + NtCurrentProcess(), + Flags, + SectionHandle, + DebugHandle, + NULL, + InJob); + + /* Load the PEB address from the hacky location where the kernel stores it */ + RemotePeb = Teb->NtTib.ArbitraryUserPointer; + + /* And restore the old TIB value */ + Teb->NtTib.ArbitraryUserPointer = TibValue; + + /* Release the large page privilege if we had acquired it */ + if (HavePrivilege) RtlReleasePrivilege(PrivilegeState); + + /* And now check if the kernel failed to create the process */ + if (!NT_SUCCESS(Status)) { - /* Set new class */ - Status = NtSetInformationProcess(hProcess, + /* Go to failure path */ + DPRINT1("Failed to create process: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* Check if there is a priority class to set */ + if (PriorityClass.PriorityClass) + { + /* Reset current privilege state */ + RealTimePrivilegeState = NULL; + + /* Is realtime priority being requested? */ + if (PriorityClass.PriorityClass == REALTIME_PRIORITY_CLASS) + { + /* Check if the caller has real-time access, and enable it if so */ + RealTimePrivilegeState = BasepIsRealtimeAllowed(TRUE); + } + + /* Set the new priority class and release the privilege */ + Status = NtSetInformationProcess(ProcessHandle, ProcessPriorityClass, &PriorityClass, sizeof(PROCESS_PRIORITY_CLASS)); - if(!NT_SUCCESS(Status)) + if (RealTimePrivilegeState) RtlReleasePrivilege(RealTimePrivilegeState); + + /* Check if we failed to set the priority class */ + if (!NT_SUCCESS(Status)) { - DPRINT1("Unable to set new process priority, status 0x%x\n", Status); + /* Bail out on failure */ + DPRINT1("Failed to set priority class: %lx\n", Status); BaseSetLastNTError(Status); - goto Cleanup; + Result = FALSE; + goto Quickie; } } - /* Set Error Mode */ + /* Check if the caller wants the default error mode */ if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE) { - ULONG ErrorMode = SEM_FAILCRITICALERRORS; - NtSetInformationProcess(hProcess, + /* Set Error Mode to only fail on critical errors */ + HardErrorMode = SEM_FAILCRITICALERRORS; + NtSetInformationProcess(ProcessHandle, ProcessDefaultHardErrorMode, - &ErrorMode, + &HardErrorMode, sizeof(ULONG)); } - /* Convert the directory to a full path */ - if (lpCurrentDirectory) + /* Check if this was a VDM binary */ + if (VdmBinaryType) { - /* Allocate a buffer */ - CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - (MAX_PATH + 1) * sizeof(WCHAR)); - if (CurrentDirectory == NULL) + /* Update VDM by telling it the process has now been created */ + VdmWaitObject = ProcessHandle; + Result = BaseUpdateVDMEntry(VdmEntryUpdateProcess, + &VdmWaitObject, + VdmTask, + VdmBinaryType); { - DPRINT1("Cannot allocate memory for directory name\n"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Cleanup; + /* Bail out on failure */ + DPRINT1("Failed to update VDM with wait object\n"); + VdmWaitObject = NULL; + goto Quickie; } - /* Get the length */ - if (GetFullPathNameW(lpCurrentDirectory, - MAX_PATH, - CurrentDirectory, - &CurrentDirectoryPart) > MAX_PATH) + /* At this point, a failure means VDM has to undo all the state */ + VdmUndoLevel |= VDM_UNDO_FULL; + } + + /* Check if VDM needed reserved low-memory */ + if (VdmReserve) + { + /* Reserve the requested allocation */ + Status = NtAllocateVirtualMemory(ProcessHandle, + &BaseAddress, + 0, + &VdmReserve, + MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + if (!NT_SUCCESS(Status)) { - DPRINT1("Directory name too long\n"); + /* Bail out on failure */ + DPRINT1("Failed to reserved memory for VDM: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + } + + /* Check if we've already queried information on the section */ + if (!QuerySection) + { + /* We haven't, so get some information about the executable */ + Status = NtQuerySection(SectionHandle, + SectionImageInformation, + &ImageInformation, + sizeof(ImageInformation), + NULL); + if (!NT_SUCCESS(Status)) + { + /* Bail out on failure */ + DPRINT1("Failed to query section: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* If we encounter a restart, don't re-query this information again */ + QuerySection = TRUE; + } + + /* Do we need to apply SxS to this image? */ + if (!(ImageInformation.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_ISOLATION)) + { + /* Too bad, we don't support this yet */ + DPRINT1("Image should receive SxS Fusion Isolation\n"); + } + + /* There's some SxS flag that we need to set if fusion flags have 1 set */ + if (FusionFlags & 1) CreateProcessMsg->Sxs.Flags |= 0x10; + + /* Check if we have a current directory */ + if (lpCurrentDirectory) + { + /* Allocate a buffer so we can keep a Unicode copy */ + DPRINT1("Current directory: %S\n", lpCurrentDirectory); + CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + (MAX_PATH * sizeof(WCHAR)) + + sizeof(UNICODE_NULL)); + if (!CurrentDirectory) + { + /* Bail out if this failed */ + BaseSetLastNTError(STATUS_NO_MEMORY); + Result = FALSE; + goto Quickie; + } + + /* Get the length in Unicode */ + Length = GetFullPathNameW(lpCurrentDirectory, + MAX_PATH, + CurrentDirectory, + &FilePart); + if (Length > MAX_PATH) + { + /* The directory is too long, so bail out */ SetLastError(ERROR_DIRECTORY); - goto Cleanup; + Result = FALSE; + goto Quickie; + } + + /* Make sure the directory is actually valid */ + CurdirLength = GetFileAttributesW(CurrentDirectory); + if ((CurdirLength == 0xffffffff) || + !(CurdirLength & FILE_ATTRIBUTE_DIRECTORY)) + { + /* It isn't, so bail out */ + DPRINT1("Current directory is invalid\n"); + SetLastError(ERROR_DIRECTORY); + Result = FALSE; + goto Quickie; } } /* Insert quotes if needed */ - if (QuotesNeeded || CmdLineIsAppName) + if ((QuotesNeeded) || (CmdLineIsAppName)) { - /* Allocate a buffer */ + /* Allocate our buffer, plus enough space for quotes and a NULL */ QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(), 0, - (wcslen(lpCommandLine) + 2 + 1) * - sizeof(WCHAR)); - if (QuotedCmdLine == NULL) + (wcslen(lpCommandLine) * sizeof(WCHAR)) + + (2 * sizeof(L'\"') + sizeof(UNICODE_NULL))); + if (QuotedCmdLine) { - DPRINT1("Cannot allocate memory for quoted command line\n"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Cleanup; - } + /* Copy the first quote */ + wcscpy(QuotedCmdLine, L"\""); - /* Copy the first quote */ - wcscpy(QuotedCmdLine, L"\""); - - /* Save a null char */ - if (QuotesNeeded) - { - SaveChar = *NullBuffer; - *NullBuffer = UNICODE_NULL; - } - - /* Add the command line and the finishing quote */ - wcscat(QuotedCmdLine, lpCommandLine); - wcscat(QuotedCmdLine, L"\""); - - /* Add the null char */ - if (QuotesNeeded) - { - *NullBuffer = SaveChar; - wcscat(QuotedCmdLine, NullBuffer); - } - - DPRINT("Quoted CmdLine: %S\n", QuotedCmdLine); - } - - if (Escape) - { - if (QuotedCmdLine == NULL) - { - QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - (wcslen(lpCommandLine) + 1) * sizeof(WCHAR)); - if (QuotedCmdLine == NULL) + /* Save the current null-character */ + if (QuotesNeeded) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Cleanup; + SaveChar = *NullBuffer; + *NullBuffer = UNICODE_NULL; } - wcscpy(QuotedCmdLine, lpCommandLine); - } - ScanString = QuotedCmdLine; - while (NULL != (ScanString = wcschr(ScanString, L'^'))) - { - ScanString++; - if (*ScanString == L'\"' || *ScanString == L'^' || *ScanString == L'\\') + /* Copy the command line and the final quote */ + wcscat(QuotedCmdLine, lpCommandLine); + wcscat(QuotedCmdLine, L"\""); + + /* Copy the null-char back */ + if (QuotesNeeded) { - memmove(ScanString-1, ScanString, wcslen(ScanString) * sizeof(WCHAR) + sizeof(WCHAR)); + *NullBuffer = SaveChar; + wcscat(QuotedCmdLine, NullBuffer); } } + else + { + /* We can't put quotes around the thing, so try it anyway */ + if (QuotesNeeded) QuotesNeeded = FALSE; + if (CmdLineIsAppName) CmdLineIsAppName = FALSE; + } } - /* Get the Process Information */ - Status = NtQueryInformationProcess(hProcess, - ProcessBasicInformation, - &ProcessBasicInfo, - sizeof(ProcessBasicInfo), - NULL); + /* Use isolation if needed */ + if (CreateProcessMsg->Sxs.Flags & 1) ParameterFlags |= 1; - /* Convert the environment */ - if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + /* Set the new command-line if needed */ + if ((QuotesNeeded) || (CmdLineIsAppName)) lpCommandLine = QuotedCmdLine; + + /* Call the helper function in charge of RTL_USER_PROCESS_PARAMETERS */ + Result = BasePushProcessParameters(ParameterFlags, + ProcessHandle, + RemotePeb, + lpApplicationName, + CurrentDirectory, + lpCommandLine, + lpEnvironment, + &StartupInfo, + dwCreationFlags | NoWindow, + bInheritHandles, + IsWowApp ? IMAGE_SUBSYSTEM_WINDOWS_GUI: 0, + AppCompatData, + AppCompatDataSize); + if (!Result) { - lpEnvironment = BasepConvertUnicodeEnvironment(&EnvSize, lpEnvironment); - if (!lpEnvironment) goto Cleanup; + /* The remote process would have an undefined state, so fail the call */ + DPRINT1("BasePushProcessParameters failed\n"); + goto Quickie; } - /* Create Process Environment */ - RemotePeb = ProcessBasicInfo.PebBaseAddress; - Ret = BasePushProcessParameters(0, - hProcess, - RemotePeb, - (LPWSTR)lpApplicationName, - CurrentDirectory, - (QuotesNeeded || CmdLineIsAppName || Escape) ? - QuotedCmdLine : lpCommandLine, - lpEnvironment, - &StartupInfo, - dwCreationFlags, - bInheritHandles, - 0, - NULL, - 0); - if (!Ret) goto Cleanup; + /* Free the VDM command line string as it's no longer needed */ + RtlFreeUnicodeString(&VdmString); + VdmString.Buffer = NULL; - /* Cleanup Environment */ - if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + /* Non-VDM console applications usually inherit handles unless specified */ + if (!(VdmBinaryType) && + !(bInheritHandles) && + !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) && + !(dwCreationFlags & (CREATE_NO_WINDOW | + CREATE_NEW_CONSOLE | + DETACHED_PROCESS)) && + (ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI)) { - RtlDestroyEnvironment(lpEnvironment); - } - - /* Close the section */ - NtClose(hSection); - hSection = NULL; - - /* Duplicate the handles if needed */ - if (!bInheritHandles && !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) && - SectionImageInfo.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI) - { - PRTL_USER_PROCESS_PARAMETERS RemoteParameters; - /* Get the remote parameters */ - Status = NtReadVirtualMemory(hProcess, + Status = NtReadVirtualMemory(ProcessHandle, &RemotePeb->ProcessParameters, - &RemoteParameters, - sizeof(PVOID), + &ProcessParameters, + sizeof(PRTL_USER_PROCESS_PARAMETERS), NULL); + if (NT_SUCCESS(Status)) + { + /* Duplicate standard input unless it's a console handle */ + if (!IsConsoleHandle(Peb->ProcessParameters->StandardInput)) + { + StuffStdHandle(ProcessHandle, + Peb->ProcessParameters->StandardInput, + &ProcessParameters->StandardInput); + } + + /* Duplicate standard output unless it's a console handle */ + if (!IsConsoleHandle(Peb->ProcessParameters->StandardOutput)) + { + StuffStdHandle(ProcessHandle, + Peb->ProcessParameters->StandardOutput, + &ProcessParameters->StandardOutput); + } + + /* Duplicate standard error unless it's a console handle */ + if (!IsConsoleHandle(Peb->ProcessParameters->StandardError)) + { + StuffStdHandle(ProcessHandle, + Peb->ProcessParameters->StandardError, + &ProcessParameters->StandardError); + } + } + } + + /* Create the Thread's Stack */ + StackSize = max(256 * 1024, ImageInformation.MaximumStackSize); + Status = BaseCreateStack(ProcessHandle, + ImageInformation.CommittedStackSize, + StackSize, + &InitialTeb); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Creating the thread stack failed: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* Create the Thread's Context */ + BaseInitializeContext(&Context, + Peb, + ImageInformation.TransferAddress, + InitialTeb.StackBase, + 0); + + /* Convert the thread attributes */ + ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, + lpThreadAttributes, + NULL); + if ((hUserToken) && (lpThreadAttributes)) + { + /* If the caller specified a user token, zero the security descriptor */ + LocalThreadAttributes = *lpThreadAttributes; + LocalThreadAttributes.lpSecurityDescriptor = NULL; + ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, + &LocalThreadAttributes, + NULL); + } + + /* Create the Kernel Thread Object */ + Status = NtCreateThread(&ThreadHandle, + THREAD_ALL_ACCESS, + ObjectAttributes, + ProcessHandle, + &ClientId, + &Context, + &InitialTeb, + TRUE); + if (!NT_SUCCESS(Status)) + { + /* A process is not allowed to exist without a main thread, so fail */ + DPRINT1("Creating the main thread failed: %lx\n", Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } + + /* Begin filling out the CSRSS message, first with our IDs and handles */ + CreateProcessMsg->ProcessHandle = ProcessHandle; + CreateProcessMsg->ThreadHandle = ThreadHandle; + CreateProcessMsg->ClientId = ClientId; + + /* Write the remote PEB address and clear it locally, we no longer use it */ + CreateProcessMsg->PebAddressNative = RemotePeb; + CreateProcessMsg->PebAddressWow64 = (ULONG)RemotePeb; + RemotePeb = NULL; + + /* Now check what kind of architecture this image was made for */ + switch (ImageInformation.Machine) + { + /* IA32, IA64 and AMD64 are supported in Server 2003 */ + case IMAGE_FILE_MACHINE_I386: + CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; + break; + case IMAGE_FILE_MACHINE_IA64: + CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64; + break; + case IMAGE_FILE_MACHINE_AMD64: + CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; + break; + + /* Anything else results in image unknown -- but no failure */ + default: + DbgPrint("kernel32: No mapping for ImageInformation.Machine == %04x\n", + ImageInformation.Machine); + CreateProcessMsg->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_UNKNOWN; + break; + } + + /* Write the input creation flags except any debugger-related flags */ + CreateProcessMsg->CreationFlags = dwCreationFlags & + ~(DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS); + + /* CSRSS needs to know if this is a GUI app or not */ + if ((ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_GUI) || + (IsWowApp)) + { + /* + * For GUI apps we turn on the 2nd bit. This allow CSRSS server dlls + * (basesrv in particular) to know whether or not this is a GUI or a + * TUI application. + */ + AddToHandle(CreateProcessMsg->ProcessHandle, 2); + + /* Also check if the parent is also a GUI process */ + NtHeaders = RtlImageNtHeader(GetModuleHandle(NULL)); + if ((NtHeaders) && + (NtHeaders->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)) + { + /* Let it know that it should display the hourglass mouse cursor */ + AddToHandle(CreateProcessMsg->ProcessHandle, 1); + } + } + + /* For all apps, if this flag is on, the hourglass mouse cursor is shown */ + if (StartupInfo.dwFlags & STARTF_FORCEONFEEDBACK) + { + AddToHandle(CreateProcessMsg->ProcessHandle, 1); + } + + /* Likewise, the opposite holds as well */ + if (StartupInfo.dwFlags & STARTF_FORCEOFFFEEDBACK) + { + RemoveFromHandle(CreateProcessMsg->ProcessHandle, 1); + } + + /* Also store which kind of VDM app (if any) this is */ + CreateProcessMsg->VdmBinaryType = VdmBinaryType; + + /* And if it really is a VDM app... */ + if (VdmBinaryType) + { + /* Store the task ID and VDM console handle */ + CreateProcessMsg->hVDM = VdmTask ? 0 : Peb->ProcessParameters->ConsoleHandle; + CreateProcessMsg->VdmTask = VdmTask; + } + else if (VdmReserve) + { + /* Extended VDM, set a flag */ + CreateProcessMsg->VdmBinaryType |= BINARY_TYPE_WOW_EX; + } + + /* Check if there's side-by-side assembly data associated with the process */ + if (CreateProcessMsg->Sxs.Flags) + { + /* This should not happen in ReactOS yet */ + DPRINT1("This is an SxS Message -- should not happen yet\n"); + BaseSetLastNTError(STATUS_NOT_IMPLEMENTED); + NtTerminateProcess(ProcessHandle, STATUS_NOT_IMPLEMENTED); + Result = FALSE; + goto Quickie; + } + + /* We are finally ready to call CSRSS to tell it about our new process! */ + CsrClientCallServer((PCSR_API_MESSAGE)&CsrMsg, + CaptureBuffer, + CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, + BasepCreateProcess), + sizeof(*CreateProcessMsg)); + + /* CSRSS has returned, free the capture buffer now if we had one */ + if (CaptureBuffer) + { + CsrFreeCaptureBuffer(CaptureBuffer); + CaptureBuffer = NULL; + } + + /* Check if CSRSS failed to accept ownership of the new Windows process */ + if (!NT_SUCCESS(CsrMsg.Status)) + { + /* Terminate the process and enter failure path with the CSRSS status */ + DPRINT1("Failed to tell csrss about new process\n"); + BaseSetLastNTError(CsrMsg.Status); + NtTerminateProcess(ProcessHandle, CsrMsg.Status); + Result = FALSE; + goto Quickie; + } + + /* Check if we have a token due to Authz/Safer, not passed by the user */ + if ((TokenHandle) && !(hUserToken)) + { + /* Replace the process and/or thread token with the one from Safer */ + Status = BasepReplaceProcessThreadTokens(TokenHandle, + ProcessHandle, + ThreadHandle); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to read memory\n"); - goto Cleanup; + /* If this failed, kill the process and enter the failure path */ + DPRINT1("Failed to update process token: %lx\n", Status); + NtTerminateProcess(ProcessHandle, Status); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; } - - /* Duplicate and write the handles */ - BasepDuplicateAndWriteHandle(hProcess, - OurPeb->ProcessParameters->StandardInput, - &RemoteParameters->StandardInput); - BasepDuplicateAndWriteHandle(hProcess, - OurPeb->ProcessParameters->StandardOutput, - &RemoteParameters->StandardOutput); - BasepDuplicateAndWriteHandle(hProcess, - OurPeb->ProcessParameters->StandardError, - &RemoteParameters->StandardError); } - /* Create the first thread */ - DPRINT("Creating thread for process (EntryPoint = 0x%p)\n", - SectionImageInfo.TransferAddress); - hThread = BasepCreateFirstThread(hProcess, - lpThreadAttributes, - &SectionImageInfo, - &ClientId, - dwCreationFlags); - - if (hThread == NULL) + /* Check if a job was associated with this process */ + if (JobHandle) { - DPRINT1("Could not create Initial Thread\n"); - /* FIXME - set last error code */ - goto Cleanup; + /* Bind the process and job together now */ + Status = NtAssignProcessToJobObject(JobHandle, ProcessHandle); + if (!NT_SUCCESS(Status)) + { + /* Kill the process and enter the failure path if binding failed */ + DPRINT1("Failed to assign process to job: %lx\n", Status); + NtTerminateProcess(ProcessHandle, STATUS_ACCESS_DENIED); + BaseSetLastNTError(Status); + Result = FALSE; + goto Quickie; + } } + /* Finally, resume the thread to actually get the process started */ if (!(dwCreationFlags & CREATE_SUSPENDED)) { - NtResumeThread(hThread, &Dummy); + NtResumeThread(ThreadHandle, &ResumeCount); } - /* Return Data */ - lpProcessInformation->dwProcessId = (DWORD)ClientId.UniqueProcess; - lpProcessInformation->dwThreadId = (DWORD)ClientId.UniqueThread; - lpProcessInformation->hProcess = hProcess; - lpProcessInformation->hThread = hThread; - DPRINT("hThread[%p]: %p inside hProcess[%p]: %p\n", hThread, - ClientId.UniqueThread, ClientId.UniqueProcess, hProcess); - hProcess = hThread = NULL; - Ret = TRUE; +VdmShortCircuit: + /* We made it this far, meaning we have a fully created process and thread */ + Result = TRUE; -Cleanup: - /* De-allocate heap strings */ - if (NameBuffer) RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); - if (ApplicationName.Buffer) - RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer); - if (CurrentDirectory) RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDirectory); - if (QuotedCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, QuotedCmdLine); + /* Anyone doing a VDM undo should now undo everything, since we are done */ + if (VdmUndoLevel) VdmUndoLevel |= VDM_UNDO_COMPLETED; - /* Kill any handles still alive */ - if (hSection) NtClose(hSection); - if (hThread) + /* Having a VDM wait object implies this must be a VDM process */ + if (VdmWaitObject) { - /* We don't know any more details than this */ - NtTerminateProcess(hProcess, STATUS_UNSUCCESSFUL); - NtClose(hThread); - } - if (hProcess) NtClose(hProcess); + /* Check if it's a 16-bit separate WOW process */ + if (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW) + { + /* OR-in the special flag to indicate this, and return to caller */ + AddToHandle(VdmWaitObject, 2); + lpProcessInformation->hProcess = VdmWaitObject; - /* Return Success */ - return Ret; + /* Check if this was a re-used VDM */ + if (VdmUndoLevel & VDM_UNDO_REUSE) + { + /* No Client ID should be returned in this case */ + ClientId.UniqueProcess = 0; + ClientId.UniqueThread = 0; + } + } + else + { + /* OR-in the special flag to indicate this is not a separate VDM */ + AddToHandle(VdmWaitObject, 1); + + /* Return handle to the caller */ + lpProcessInformation->hProcess = VdmWaitObject; + } + + /* Close the original process handle, since it's not needed for VDM */ + if (ProcessHandle) NtClose(ProcessHandle); + } + else + { + /* This is a regular process, so return the real process handle */ + lpProcessInformation->hProcess = ProcessHandle; + } + + /* Return the rest of the process information based on what we have so far */ + lpProcessInformation->hThread = ThreadHandle; + lpProcessInformation->dwProcessId = HandleToUlong(ClientId.UniqueProcess); + lpProcessInformation->dwThreadId = HandleToUlong(ClientId.UniqueThread); + + /* NULL these out here so we know to treat this as a success scenario */ + ProcessHandle = NULL; + ThreadHandle = NULL; + +Quickie: + /* Free the debugger command line if one was allocated */ + if (DebuggerCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine); + + /* Check if an SxS full path as queried */ + if (PathBuffer) + { + /* Reinitialize the executable path */ + RtlInitEmptyUnicodeString(&SxsWin32ExePath, NULL, 0); + SxsWin32ExePath.Length = 0; + + /* Free the path buffer */ + RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer); + } + +#if _SXS_SUPPORT_ENABLED_ + /* Check if this was a non-VDM process */ + if (!VdmBinaryType) + { + /* Then it must've had SxS data, so close the handles used for it */ + BasepSxsCloseHandles(&Handles); + BasepSxsCloseHandles(&FileHandles); + + /* Check if we built SxS byte buffers for this create process request */ + if (SxsConglomeratedBuffer) + { + /* Loop all of them */ + for (i = 0; i < 5; i++) + { + /* Check if this one was allocated */ + ThisBuffer = SxsStaticBuffers[i]; + if (ThisBuffer) + { + /* Get the underlying RTL_BUFFER structure */ + ByteBuffer = &ThisBuffer->ByteBuffer; + if ((ThisBuffer != (PVOID)-8) && (ByteBuffer->Buffer)) + { + /* Check if it was dynamic */ + if (ByteBuffer->Buffer != ByteBuffer->StaticBuffer) + { + /* Free it from the heap */ + FreeString.Buffer = (PWCHAR)ByteBuffer->Buffer; + RtlFreeUnicodeString(&FreeString); + } + + /* Reset the buffer to its static data */ + ByteBuffer->Buffer = ByteBuffer->StaticBuffer; + ByteBuffer->Size = ByteBuffer->StaticSize; + } + + /* Reset the string to the static buffer */ + RtlInitEmptyUnicodeString(&ThisBuffer->String, + (PWCHAR)ByteBuffer->StaticBuffer, + ByteBuffer->StaticSize); + if (ThisBuffer->String.Buffer) + { + /* Also NULL-terminate it */ + *ThisBuffer->String.Buffer = UNICODE_NULL; + } + } + } + } + } +#endif + /* Check if an environment was passed in */ + if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + { + /* Destroy it */ + RtlDestroyEnvironment(lpEnvironment); + + /* If this was the VDM environment too, clear that as well */ + if (VdmUnicodeEnv.Buffer == lpEnvironment) VdmUnicodeEnv.Buffer = NULL; + lpEnvironment = NULL; + } + + /* Unconditionally free all the name parsing buffers we always allocate */ + RtlFreeHeap(RtlGetProcessHeap(), 0, QuotedCmdLine); + RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); + RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDirectory); + RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer); + + /* Close open file/section handles */ + if (FileHandle) NtClose(FileHandle); + if (SectionHandle) NtClose(SectionHandle); + + /* If we have a thread handle, this was a failure path */ + if (ThreadHandle) + { + /* So kill the process and close the thread handle */ + NtTerminateProcess(ProcessHandle, 0); + NtClose(ThreadHandle); + } + + /* If we have a process handle, this was a failure path, so close it */ + if (ProcessHandle) NtClose(ProcessHandle); + + /* Thread/process handles, if any, are now processed. Now close this one. */ + if (JobHandle) NtClose(JobHandle); + + /* Check if we had created a token */ + if (TokenHandle) + { + /* And if the user asked for one */ + if (hUserToken) + { + /* Then return it */ + *hNewToken = TokenHandle; + } + else + { + /* User didn't want it, so we used it temporarily -- close it */ + NtClose(TokenHandle); + } + } + + /* Free any temporary app compatibility data, it's no longer needed */ + BasepFreeAppCompatData(AppCompatData, AppCompatSxsData); + + /* Free a few strings. The API takes care of these possibly being NULL */ + RtlFreeUnicodeString(&VdmString); + RtlFreeUnicodeString(&DebuggerString); + + /* Check if we had built any sort of VDM environment */ + if ((VdmAnsiEnv.Buffer) || (VdmUnicodeEnv.Buffer)) + { + /* Free it */ + BaseDestroyVDMEnvironment(&VdmAnsiEnv, &VdmUnicodeEnv); + } + + /* Check if this was any kind of VDM application that we ended up creating */ + if ((VdmUndoLevel) && (!(VdmUndoLevel & VDM_UNDO_COMPLETED))) + { + /* Send an undo */ + BaseUpdateVDMEntry(VdmEntryUndo, + (PHANDLE)&VdmTask, + VdmUndoLevel, + VdmBinaryType); + + /* And close whatever VDM handle we were using for notifications */ + if (VdmWaitObject) NtClose(VdmWaitObject); + } + + /* Check if we ended up here with an allocated search path, and free it */ + if (SearchPath) RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath); + + /* Finally, return the API's result */ + return Result; } /* @@ -3322,7 +4602,7 @@ CreateProcessW(LPCWSTR lpApplicationName, LPPROCESS_INFORMATION lpProcessInformation) { /* Call the internal (but exported) version */ - return CreateProcessInternalW(0, + return CreateProcessInternalW(NULL, lpApplicationName, lpCommandLine, lpProcessAttributes, @@ -3490,7 +4770,7 @@ CreateProcessA(LPCSTR lpApplicationName, LPPROCESS_INFORMATION lpProcessInformation) { /* Call the internal (but exported) version */ - return CreateProcessInternalA(0, + return CreateProcessInternalA(NULL, lpApplicationName, lpCommandLine, lpProcessAttributes, diff --git a/dll/win32/kernel32/client/vdm.c b/dll/win32/kernel32/client/vdm.c index bfbde543b6e..69a701079db 100644 --- a/dll/win32/kernel32/client/vdm.c +++ b/dll/win32/kernel32/client/vdm.c @@ -73,7 +73,8 @@ BaseCheckVDM(IN ULONG BinaryType, IN PCSR_API_MESSAGE ApiMessage, IN OUT PULONG iTask, IN DWORD CreationFlags, - IN LPSTARTUPINFOW StartupInfo) + IN LPSTARTUPINFOW StartupInfo, + IN HANDLE hUserToken OPTIONAL) { /* This is not supported */ UNIMPLEMENTED; diff --git a/dll/win32/kernel32/include/kernel32.h b/dll/win32/kernel32/include/kernel32.h index 9a203d75a39..9e5e6659dcb 100644 --- a/dll/win32/kernel32/include/kernel32.h +++ b/dll/win32/kernel32/include/kernel32.h @@ -410,13 +410,13 @@ BasepLocateExeLdrEntry(IN PLDR_DATA_TABLE_ENTRY Entry, typedef NTSTATUS (NTAPI *PBASEP_APPCERT_PLUGIN_FUNC)( - IN PCHAR ApplicationName, + IN LPWSTR ApplicationName, IN ULONG CertFlag ); typedef NTSTATUS (NTAPI *PBASEP_APPCERT_EMBEDDED_FUNC)( - IN PCHAR ApplicationName + IN LPWSTR ApplicationName ); typedef NTSTATUS @@ -491,6 +491,22 @@ BaseCheckForVDM( OUT LPDWORD ExitCode ); +BOOL +WINAPI +BaseCheckVDM( + IN ULONG BinaryType, + IN PCWCH ApplicationName, + IN PCWCH CommandLine, + IN PCWCH CurrentDirectory, + IN PANSI_STRING AnsiEnvironment, + IN PCSR_API_MESSAGE ApiMessage, + IN OUT PULONG iTask, + IN DWORD CreationFlags, + IN LPSTARTUPINFOW StartupInfo, + IN HANDLE hUserToken OPTIONAL +); + + /* FIXME: This is EXPORTED! It should go in an external kernel32.h header */ VOID WINAPI @@ -498,3 +514,14 @@ BasepFreeAppCompatData( IN PVOID AppCompatData, IN PVOID AppCompatSxsData ); + +NTSTATUS +WINAPI +BasepCheckWinSaferRestrictions( + IN HANDLE UserToken, + IN LPWSTR ApplicationName, + IN HANDLE FileHandle, + OUT PBOOLEAN InJob, + OUT PHANDLE NewToken, + OUT PHANDLE JobHandle +); diff --git a/dll/win32/syssetup/classinst.c b/dll/win32/syssetup/classinst.c index dc853e9df4e..5c3a4d0a754 100644 --- a/dll/win32/syssetup/classinst.c +++ b/dll/win32/syssetup/classinst.c @@ -11,6 +11,45 @@ #define NDEBUG #include + +/* + * @unimplemented + */ +DWORD +WINAPI +ComputerClassInstaller( + IN DI_FUNCTION InstallFunction, + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + switch (InstallFunction) + { + default: + DPRINT1("Install function %u ignored\n", InstallFunction); + return ERROR_DI_DO_DEFAULT; + } +} + + +/* + * @unimplemented + */ +DWORD +WINAPI +DeviceBayClassInstaller( + IN DI_FUNCTION InstallFunction, + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + switch (InstallFunction) + { + default: + DPRINT("Install function %u ignored\n", InstallFunction); + return ERROR_DI_DO_DEFAULT; + } +} + + /* * @implemented */ @@ -61,3 +100,62 @@ MouseClassInstaller( return ERROR_DI_DO_DEFAULT; } } + + +/* + * @unimplemented + */ +DWORD +WINAPI +NtApmClassInstaller( + IN DI_FUNCTION InstallFunction, + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + switch (InstallFunction) + { + default: + DPRINT("Install function %u ignored\n", InstallFunction); + return ERROR_DI_DO_DEFAULT; + } +} + + +/* + * @unimplemented + */ +DWORD +WINAPI +ScsiClassInstaller( + IN DI_FUNCTION InstallFunction, + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + switch (InstallFunction) + { + default: + DPRINT("Install function %u ignored\n", InstallFunction); + return ERROR_DI_DO_DEFAULT; + } +} + + +/* + * @unimplemented + */ +DWORD +WINAPI +TapeClassInstaller( + IN DI_FUNCTION InstallFunction, + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + switch (InstallFunction) + { + default: + DPRINT("Install function %u ignored\n", InstallFunction); + return ERROR_DI_DO_DEFAULT; + } +} + +/* EOF */ diff --git a/dll/win32/syssetup/syssetup.spec b/dll/win32/syssetup/syssetup.spec index 4b37986a416..e2f4a1d8296 100644 --- a/dll/win32/syssetup/syssetup.spec +++ b/dll/win32/syssetup/syssetup.spec @@ -8,13 +8,13 @@ @ stub AsrpGetLocalVolumeInfo @ stub AsprRestoreNonCriticalDisksW @ stub CdromPropPageProvider -@ stub ComputerClassInstaller +@ stdcall ComputerClassInstaller(long ptr ptr) @ stub CreateLocalAdminAccount @ stub CreateLocalAdminAccountEx @ stub CreateLocalUserAccount @ stub CriticalDeviceCoInstaller @ stub DevInstallW -@ stub DeviceBayClassInstaller +@ stdcall DeviceBayClassInstaller(long ptr ptr) @ stub DiskPropPageProvider @ stub DoInstallComponentInfs @ stub EisaUpHalCoInstaller @@ -29,7 +29,7 @@ @ stub LegacyDriverPropPageProvider @ stub MigrateExceptionPackages @ stdcall MouseClassInstaller(long ptr ptr) -@ stub NtApmClassInstaller +@ stdcall NtApmClassInstaller(long ptr ptr) @ stub OpkCheckVersion @ stub PS2MousePropPageProvider @ stub PnPInitializationThread @@ -37,7 +37,7 @@ @ stub RepairStartMenuItems @ stub ReportError @ stub RunOEMExtraTasks -@ stub ScsiClassInstaller +@ stdcall ScsiClassInstaller(long ptr ptr) @ stub SetAccountDomainSid @ stub SetupAddOrRemoveTestCertificate @ stdcall SetupChangeFontSize(ptr wstr) @@ -76,7 +76,7 @@ @ stub SetupUnregisterOsComponent @ stub StorageCoInstaller @ stub SystemUpdateUserProfileDirectory -@ stub TapeClassInstaller +@ stdcall TapeClassInstaller(long ptr ptr) @ stub TapePropPageProvider @ stdcall TerminateSetupActionLog() @ stub UpdatePnpDeviceDrivers diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index fcfaa9396d8..be7f2a02b76 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -12,6 +12,7 @@ add_subdirectory(input) add_subdirectory(ksfilter) add_subdirectory(network) add_subdirectory(parallel) +add_subdirectory(sac) add_subdirectory(serial) add_subdirectory(setup) add_subdirectory(storage) diff --git a/drivers/sac/CMakeLists.txt b/drivers/sac/CMakeLists.txt new file mode 100644 index 00000000000..987710ae04a --- /dev/null +++ b/drivers/sac/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_subdirectory(driver) diff --git a/drivers/sac/driver/CMakeLists.txt b/drivers/sac/driver/CMakeLists.txt new file mode 100644 index 00000000000..1a28f98b485 --- /dev/null +++ b/drivers/sac/driver/CMakeLists.txt @@ -0,0 +1,20 @@ + +list(APPEND SOURCE + chanmgr.c + channel.c + cmdchan.c + concmd.c + conmgr.c + data.c + dispatch.c + init.c + memory.c + rawchan.c + util.c + vtutf8chan.c) + +add_library(sacdrv SHARED ${SOURCE} sacdrv.rc) +set_module_type(sacdrv kernelmodedriver) +add_importlibs(sacdrv ntoskrnl hal) +add_dependencies(sacdrv sacmsg) +add_cd_file(TARGET sacdrv DESTINATION reactos/system32/drivers NO_CAB FOR all) diff --git a/drivers/sac/driver/chanmgr.c b/drivers/sac/driver/chanmgr.c index 1a655d92c02..a005a1e98c8 100644 --- a/drivers/sac/driver/chanmgr.c +++ b/drivers/sac/driver/chanmgr.c @@ -1,176 +1,717 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/chanmgr.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/chanmgr.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +SAC_CHANNEL_LOCK ChannelCreateLock; +BOOLEAN ChannelCreateEnabled; +PSAC_CHANNEL ChannelArray[SAC_MAX_CHANNELS]; +LONG ChannelRefCount[SAC_MAX_CHANNELS]; +LONG ChannelReaped[SAC_MAX_CHANNELS]; +SAC_CHANNEL_LOCK ChannelSlotLock[SAC_MAX_CHANNELS]; +LONG CurrentChannelRefCount; +KMUTEX CurrentChannelLock; -NTSTATUS -ChanMgrInitialize( - VOID - ) +/* FUNCTIONS *****************************************************************/ + +#define MAX_REF_COUNT 100 + +#define CHANNEL_SLOT_IS_IN_USE(x) (ChannelRefCount[(x)] > 0) + +FORCEINLINE +PSAC_CHANNEL +ChannelFromIndex(IN ULONG Index) { - return STATUS_NOT_IMPLEMENTED; + return ChannelArray[Index]; } -NTSTATUS -ChanMgrGetChannelIndex( - IN PSAC_CHANNEL Channel, - IN PULONG ChannelIndex - ) +FORCEINLINE +LONG +ChannelGetReferenceCount(IN LONG Index) { - return STATUS_NOT_IMPLEMENTED; + return ChannelRefCount[Index]; } -NTSTATUS -ChanMgrReleaseChannel( - IN PSAC_CHANNEL Channel - ) +FORCEINLINE +LONG +ChannelReferenceByIndex(IN LONG Index) { - return STATUS_NOT_IMPLEMENTED; + if (ChannelGetReferenceCount(Index) > 0) + { + ASSERT(ChannelRefCount[Index] <= MAX_REF_COUNT); + ASSERT(ChannelRefCount[Index] >= 1); + _InterlockedIncrement(&ChannelRefCount[Index]); + ASSERT(ChannelRefCount[Index] <= MAX_REF_COUNT); + ASSERT(ChannelRefCount[Index] >= 2); + } + + return ChannelGetReferenceCount(Index); } -NTSTATUS -ChanMgrGetByHandle( - IN PSAC_CHANNEL_ID ChannelId, - OUT PSAC_CHANNEL pChannel - ) +FORCEINLINE +LONG +ChannelReferenceByIndexWithLock(IN LONG Index) { - return STATUS_NOT_IMPLEMENTED; + LONG RefCount; + + ChannelSlotLock(Index); + RefCount = ChannelReferenceByIndex(Index); + ChannelSlotUnlock(Index); + return RefCount; } -NTSTATUS -ChanMgrGetByHandleAndFileObject( - IN PSAC_CHANNEL_ID ChannelId, - IN PFILE_OBJECT FileObject, - OUT PSAC_CHANNEL pChannel - ) +FORCEINLINE +LONG +ChannelDereferenceByIndex(IN LONG Index) { - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChanMgrGetChannelByName( - IN PWCHAR Name, - OUT PSAC_CHANNEL pChannel - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChanMgrGetByIndex( - IN ULONG TargetIndex, - IN PSAC_CHANNEL *TargetChannel - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChanMgrGetNextActiveChannel( - IN PSAC_CHANNEL CurrentChannel, - IN PULONG TargetIndex, - OUT PSAC_CHANNEL *TargetChannel - ) -{ - return STATUS_NOT_IMPLEMENTED; + ASSERT(ChannelGetReferenceCount(Index) <= MAX_REF_COUNT); + ASSERT(ChannelGetReferenceCount(Index) > 1); + _InterlockedDecrement(&ChannelRefCount[Index]); + ASSERT(ChannelGetReferenceCount(Index) >= 1); + return ChannelGetReferenceCount(Index); } +FORCEINLINE VOID -ChanMgrChannelDestroy( - IN PSAC_CHANNEL Channel - ) +ChannelDereferenceByIndexWithLock(IN LONG Index) { + ChannelSlotLock(Index); + ChannelDereferenceByIndex(Index); + ChannelSlotUnlock(Index); +} +FORCEINLINE +VOID +ChannelDereferenceToZeroByIndex(IN LONG Index) +{ + ASSERT(ChannelGetReferenceCount(Index) == 1); + ASSERT(ChannelIsActive(ChannelFromIndex(Index)) == FALSE); + _InterlockedExchange(&ChannelRefCount[Index], 0); +} + +FORCEINLINE +VOID +ChannelReferenceToOneByIndex(IN LONG Index) +{ + ASSERT(ChannelGetReferenceCount(Index) == 0); + _InterlockedExchange(&ChannelRefCount[Index], 1); +} + +FORCEINLINE +VOID +ChannelReferenceToOneByIndexWithLock(IN LONG Index) +{ + ChannelSlotLock(Index); + ASSERT(ChannelGetReferenceCount((Index)) == 1); + _InterlockedExchange(&ChannelRefCount[Index], 1); + ChannelSlotUnlock(Index); } NTSTATUS -ChanMgrCloseChannel( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChanMgrInitialize(VOID) { - return STATUS_NOT_IMPLEMENTED; + ULONG i; + + /* Initialize the channel lock */ + SacInitializeLock(&ChannelCreateLock); + ChannelCreateEnabled = TRUE; + + /* Loop through the channel arrays */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Clear and initialize their locks */ + ChannelArray[i] = NULL; + SacInitializeLock(&ChannelSlotLock[i]); + + /* Clear their statuses and reference counts */ + _InterlockedExchange(&ChannelRefCount[i], 0); + _InterlockedExchange(&ChannelReaped[i], 1); + } + + /* All good */ + return STATUS_SUCCESS; } NTSTATUS -ChanMgrReapChannel( - IN ULONG ChannelIndex - ) +NTAPI +ChanMgrShutdown(VOID) { - return STATUS_NOT_IMPLEMENTED; + /* FIXME: TODO */ + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -ChanMgrReapChannels( - VOID - ) +NTAPI +ChanMgrGetChannelByName(IN PWCHAR Name, + OUT PSAC_CHANNEL* Channel) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status, Status1; + ULONG i; + PSAC_CHANNEL CurrentChannel; + PWCHAR ChannelName; + BOOLEAN Found; + CHECK_PARAMETER1(Name); + CHECK_PARAMETER2(Channel); + + /* Assume failure */ + *Channel = NULL; + Status = STATUS_NOT_FOUND; + + /* Loop through all channels */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Reference this one and check if it's valid */ + if (ChannelReferenceByIndexWithLock(i) > 0) + { + /* All good, grab it */ + CurrentChannel = ChannelFromIndex(i); + ASSERT(CurrentChannel != NULL); + + /* Get its name */ + Status1 = ChannelGetName(CurrentChannel, &ChannelName); + ASSERT(NT_SUCCESS(Status1)); + + /* Check if this is the name that was passed in */ + Found = wcsicmp(Name, ChannelName); + SacFreePool(ChannelName); + if (Found) + { + /* We found it, return it (with a reference held) */ + *Channel = CurrentChannel; + return STATUS_SUCCESS; + } + + /* Not the one we want, dereference this one and keep going */ + ChannelDereferenceByIndexWithLock(i); + } + } + + /* No channels with this name were found */ + return Status; } NTSTATUS -ChanMgrGetChannelCount( - OUT PULONG ChannelCount - ) +NTAPI +ChanMgrGetByHandle(IN SAC_CHANNEL_ID ChannelId, + OUT PSAC_CHANNEL* TargetChannel) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + ULONG i; + PSAC_CHANNEL Channel; + CHECK_PARAMETER2(TargetChannel); + + /* Assume failure */ + *TargetChannel = NULL; + Status = STATUS_NOT_FOUND; + + /* Loop through all channels */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Reference this one and check if it's valid */ + if (ChannelReferenceByIndexWithLock(i) > 0) + { + /* All good, grab it */ + Channel = ChannelFromIndex(i); + ASSERT(Channel != NULL); + + /* Check if the channel ID matches */ + if (ChannelIsEqual(Channel, &ChannelId)) + { + /* We found it, return it (with a reference held) */ + *TargetChannel = Channel; + return STATUS_SUCCESS; + } + + /* Not the one we want, dereference this one and keep going */ + ChannelDereferenceByIndexWithLock(i); + } + } + + /* No channels with this ID were found */ + return Status; } NTSTATUS -ChanMgrIsFull( - OUT PBOOLEAN IsFull - ) +NTAPI +ChanMgrReleaseChannel(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; -} + LONG Index; + ULONG RefCount; + PSAC_CHANNEL ThisChannel; + CHECK_PARAMETER(Channel); -NTSTATUS -ChanMgrShutdown( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; + /* Get the index of the channel */ + Index = ChannelGetIndex(Channel); + + /* Drop a reference -- there should still be at least the keepalive left */ + ChannelSlotLock(Index); + RefCount = ChannelDereferenceByIndex(Index); + ASSERT(RefCount > 0); + + /* Do we only have the keep-alive left, and the channel is dead? */ + if ((RefCount == 1) && !(ChannelIsActive(Channel))) + { + /* Check if the ??? flag is set, or if there's no output data */ + ThisChannel = ChannelFromIndex(Index); + if (!(ThisChannel->Flags & 1)) + { + /* Nope, we can wipe the references and get rid of it */ + ChannelDereferenceToZeroByIndex(Index); + } + else if (!ThisChannel->ChannelHasNewOBufferData) + { + /* No data, we can wipe the references and get rid of it */ + ChannelDereferenceToZeroByIndex(Index); + } + } + + /* We're done, we can unlock the slot now */ + ChannelSlotUnlock(Index); + return STATUS_SUCCESS; } BOOLEAN -ChanMgrIsUniqueName( - IN PWCHAR ChannelName - ) +NTAPI +ChanMgrIsUniqueName(IN PWCHAR ChannelName) { - return FALSE; + NTSTATUS Status; + BOOLEAN IsUnique = FALSE; + PSAC_CHANNEL Channel; + + /* Check if a channel with this name already exists */ + Status = ChanMgrGetChannelByName(ChannelName, &Channel); + if (Status == STATUS_NOT_FOUND) IsUnique = TRUE; + + /* If one did, dereference it, all we wanted was to check uniqueness */ + if (NT_SUCCESS(Status)) ChanMgrReleaseChannel(Channel); + + /* Return if one was found or not */ + return IsUnique; } NTSTATUS -ChanMgrGenerateUniqueCmdName( - IN PWCHAR ChannelName - ) +NTAPI +ChanMgrReapChannel(IN ULONG ChannelIndex) { - return STATUS_NOT_IMPLEMENTED; + /* FIXME: TODO */ + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -ChanMgrCreateChannel( - OUT PSAC_CHANNEL *Channel, - IN PSAC_CHANNEL_ATTRIBUTES Attributes - ) +NTAPI +ChanMgrReapChannels(VOID) { - return STATUS_NOT_IMPLEMENTED; + ULONG i; + NTSTATUS Status = STATUS_SUCCESS; + + /* Loop all the channels */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Lock this index and see if the channel was reaped */ + ChannelSlotLock(i); + if (!ChannelReaped[i]) + { + /* It was not reaped yet, so a channel should still be here */ + ASSERT(ChannelFromIndex(i) != NULL); + if (ChannelGetReferenceCount(i) <= 0) + { + /* The channel has no more references, so clear the buffer flags */ + _InterlockedExchange(&ChannelArray[i]->ChannelHasNewIBufferData, 0); + _InterlockedExchange(&ChannelArray[i]->ChannelHasNewOBufferData, 0); + + /* And reap it */ + Status = ChanMgrReapChannel(i); + } + } + + /* Release the lock, and move on unless reaping failed */ + ChannelSlotUnlock(i); + if (!NT_SUCCESS(Status)) break; + } + + /* Return reaping status */ + return Status; } NTSTATUS -ChanMgrCloseChannelsWithFileObject( - IN PFILE_OBJECT FileObject - ) +NTAPI +ChanMgrCreateChannel(OUT PSAC_CHANNEL *Channel, + IN PSAC_CHANNEL_ATTRIBUTES Attributes) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + PSAC_CHANNEL NewChannel; + SAC_CHANNEL_ID ChanId; + ULONG i; + CHECK_PARAMETER(Channel); + CHECK_PARAMETER2(Attributes); + + /* No other channel create attempts can happen */ + ChannelLockCreates(); + + /* Is the channel manager initialized? */ + if (ChannelCreateEnabled) + { + /* Nope, bail out */ + Status = STATUS_UNSUCCESSFUL; + goto ReturnStatus; + } + + /* Reap any zombie channels */ + Status = ChanMgrReapChannels(); + if (!NT_SUCCESS(Status)) + { + /* Bail out on error */ + Status = STATUS_UNSUCCESSFUL; + goto ReturnStatus; + } + + /* Check if we already have a channel with this name */ + if (!ChanMgrIsUniqueName(Attributes->NameBuffer)) + { + /* We do, fail */ + Status = STATUS_DUPLICATE_NAME; + goto ReturnStatus; + } + + /* Allocate this channel */ + NewChannel = SacAllocatePool(sizeof(SAC_CHANNEL), CHANNEL_BLOCK_TAG); + CHECK_PARAMETER_WITH_STATUS(NewChannel, STATUS_NO_MEMORY); // bug + RtlZeroMemory(NewChannel, sizeof(SAC_CHANNEL)); + + /* Loop channel slots */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Find a free spot for it */ + if (ChannelReaped[i]) + { + /* Free slot found, attempt to use it */ + ASSERT(!CHANNEL_SLOT_IS_IN_USE(i)); + _InterlockedCompareExchange((PLONG)&ChannelArray[i], (LONG)NewChannel, 0); + if (ChannelArray[i] == NewChannel) break; + } + } + + /* Did we not find a single free slot? */ + if (i == SAC_MAX_CHANNELS) + { + /* Bail out */ + Status = STATUS_UNSUCCESSFUL; + goto ReturnStatus; + } + + /* Create an ID for this channel */ + RtlZeroMemory(&ChanId, sizeof(ChanId)); + Status = ExUuidCreate(&ChanId.ChannelGuid); + if (!NT_SUCCESS(Status)) + { + /* Bail out if we couldn't */ + SAC_DBG(SAC_DBG_INIT, "SAC Create Channel :: Failed to get GUID\n"); + goto ReturnStatus; + } + + /* Now create the channel proper */ + Status = ChannelCreate(NewChannel, Attributes, ChanId); + if (NT_SUCCESS(Status)) + { + /* Set the channel index */ + _InterlockedExchange(&NewChannel->Index, i); + + /* Add the initial reference to the channel */ + ChannelReferenceToOneByIndexWithLock(i); + + /* Return it to the caller */ + *Channel = NewChannel; + + /* This slot is now occupied */ + ASSERT(ChannelReaped[i] == 1); + _InterlockedExchange(&ChannelReaped[i], 0); + } + else + { + /* We couldn't create it, free the buffer */ + SacFreePool(NewChannel); + } + +ReturnStatus: + /* Return whatever the operation status was */ + ChannelUnlockCreates(); + return Status; +} + +NTSTATUS +NTAPI +ChanMgrGetByHandleAndFileObject(IN SAC_CHANNEL_ID ChannelId, + IN PFILE_OBJECT FileObject, + OUT PSAC_CHANNEL* TargetChannel) +{ + NTSTATUS Status; + PSAC_CHANNEL FoundChannel; + + /* Lookup the channel by ID first */ + Status = ChanMgrGetByHandle(ChannelId, &FoundChannel); + if (NT_SUCCESS(Status)) + { + /* We found it, now check if the file object matches */ + if (FoundChannel->FileObject == FileObject) + { + /* Yep, return success */ + *TargetChannel = FoundChannel; + } + else + { + /* Nope, drop the reference on the channel */ + ChanMgrReleaseChannel(FoundChannel); + + /* And return failure */ + *TargetChannel = NULL; + Status = STATUS_NOT_FOUND; + } + } + + /* Return if we found it or not */ + return Status; +} + +NTSTATUS +NTAPI +ChanMgrGetChannelIndex(IN PSAC_CHANNEL Channel, + IN PLONG ChannelIndex) +{ + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(ChannelIndex); + + /* Just return the index of the channel */ + *ChannelIndex = ChannelGetIndex(Channel); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChanMgrGetByIndex(IN LONG TargetIndex, + IN PSAC_CHANNEL* TargetChannel) +{ + NTSTATUS Status; + CHECK_PARAMETER1(TargetIndex < SAC_MAX_CHANNELS); + CHECK_PARAMETER2(TargetChannel); + + /* Assume failure */ + *TargetChannel = NULL; + Status = STATUS_NOT_FOUND; + + /* Reference this one and check if it's valid */ + if (ChannelReferenceByIndexWithLock(TargetIndex) > 0) + { + /* We found it, return it (with a reference held) */ + *TargetChannel = ChannelFromIndex(TargetIndex); + return STATUS_SUCCESS; + } + + /* No channels with this ID were found */ + return Status; +} + +NTSTATUS +NTAPI +ChanMgrGetNextActiveChannel(IN PSAC_CHANNEL CurrentChannel, + IN PULONG TargetIndex, + OUT PSAC_CHANNEL *TargetChannel) +{ + NTSTATUS Status; + ULONG i; + LONG ChannelIndex, StartIndex; + PSAC_CHANNEL FoundChannel; + BOOLEAN ChannelFound; + CHECK_PARAMETER1(CurrentChannel); + CHECK_PARAMETER2(TargetIndex); + CHECK_PARAMETER3(TargetChannel); + + /* Get the current channel index */ + Status = ChanMgrGetChannelIndex(CurrentChannel, &ChannelIndex); + if (!NT_SUCCESS(Status)) return Status; + + /* Assume failure */ + ChannelFound = FALSE; + + /* Loop through all the possible active channels */ + StartIndex = (ChannelIndex + 1) % SAC_MAX_CHANNELS; + for (i = StartIndex; i != StartIndex; i = (i + 1) % SAC_MAX_CHANNELS) + { + /* Get the channel and see if it exists*/ + Status = ChanMgrGetByIndex(i, &FoundChannel); + if (Status != STATUS_NOT_FOUND) + { + /* Bail out if we failed for some reason */ + if (!NT_SUCCESS(Status)) return Status; + + /* It exists -- is it active? Or, does it have output data? */ + if ((ChannelIsActive(FoundChannel)) || + (!(ChannelIsActive(FoundChannel)) && + (FoundChannel->ChannelHasNewOBufferData))) + { + /* It's active or has output data, return with it */ + ChannelFound = TRUE; + break; + } + + /* Drop the reference on this channel and try the next one */ + Status = ChanMgrReleaseChannel(FoundChannel); + if (!NT_SUCCESS(Status)) return Status; + } + } + + /* Check if we successfully found a channel */ + if ((NT_SUCCESS(Status)) && (ChannelFound)) + { + /* Return it and its indexed. Remember we still hold the reference */ + *TargetIndex = i; + *TargetChannel = FoundChannel; + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +ChanMgrChannelDestroy(IN PSAC_CHANNEL Channel) +{ + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER(ChannelGetReferenceCount(Channel->Index) > 0); + + /* Destroy the channel */ + return Channel->ChannelDestroy(Channel); +} + +NTSTATUS +NTAPI +ChanMgrCloseChannel(IN PSAC_CHANNEL Channel) +{ + NTSTATUS Status; + CHECK_PARAMETER(Channel); + + /* Check if the channel is active */ + if (ChannelIsActive(Channel)) + { + /* Yep, close it */ + Status = ChannelClose(Channel); + } + else + { + /* Nothing to do */ + Status = STATUS_ALREADY_DISCONNECTED; + } + + /* Handle the channel close */ + ConMgrHandleEvent(TRUE, Channel, &Status); + return Status; +} + +NTSTATUS +NTAPI +ChanMgrGetChannelCount(OUT PULONG ChannelCount) +{ + ULONG i; + PSAC_CHANNEL Channel; + NTSTATUS Status; + CHECK_PARAMETER(ChannelCount); + + /* Assume no channels */ + *ChannelCount = 0; + + /* Loop every channel */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* See if this one exists */ + Status = ChanMgrGetByIndex(i, &Channel); + if (Status != STATUS_NOT_FOUND) + { + /* Sanity checks*/ + ASSERT(NT_SUCCESS(Status)); + ASSERT(Channel != NULL); + + /* It exists -- is it active? Or, does it have output data? */ + if ((ChannelIsActive(Channel)) || + (!(ChannelIsActive(Channel)) && + (Channel->ChannelHasNewOBufferData))) + { + /* It's active or has output data, increase the count */ + ++*ChannelCount; + break; + } + + /* Drop the reference on this channel and try the next one */ + Status = ChanMgrReleaseChannel(Channel); + if (!NT_SUCCESS(Status)) return Status; + } + else + { + /* Channel doesn't exist, nothing wrong with that, keep going */ + Status = STATUS_SUCCESS; + } + } + + /* We should always succeed if we get here */ + ASSERT(NT_SUCCESS(Status)); + return Status; +} + +NTSTATUS +NTAPI +ChanMgrIsFull(OUT PBOOLEAN IsFull) +{ + NTSTATUS Status; + ULONG Count; + + /* Count the channels */ + Status = ChanMgrGetChannelCount(&Count); + CHECK_PARAMETER(Status == STATUS_SUCCESS); + + /* Return if we hit the limit */ + *IsFull = (Count == SAC_MAX_CHANNELS); + return Status; +} + +NTSTATUS +NTAPI +ChanMgrCloseChannelsWithFileObject(IN PFILE_OBJECT FileObject) +{ + PSAC_CHANNEL Channel; + ULONG i; + NTSTATUS Status; + CHECK_PARAMETER1(FileObject); + + /* Loop all channels */ + for (i = 0; i < SAC_MAX_CHANNELS; i++) + { + /* Try to get this one */ + Status = ChanMgrGetByIndex(i, &Channel); + if (!NT_SUCCESS(Status)) break; + + /* Check if the FO matches, if so, close the channel */ + if (Channel->FileObject == FileObject) ChanMgrCloseChannel(Channel); + + /* Drop the reference and try the next channel(s) */ + Status = ChanMgrReleaseChannel(Channel); + if (!NT_SUCCESS(Status)) break; + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +ChanMgrGenerateUniqueCmdName(IN PWCHAR ChannelName) +{ + return STATUS_NOT_IMPLEMENTED; } diff --git a/drivers/sac/driver/channel.c b/drivers/sac/driver/channel.c index 154097ebec0..0ee165d7066 100644 --- a/drivers/sac/driver/channel.c +++ b/drivers/sac/driver/channel.c @@ -1,318 +1,568 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/channel.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/channel.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ BOOLEAN -ChannelIsValidType( - IN SAC_CHANNEL_TYPE ChannelType - ) +NTAPI +ChannelIsValidType(IN SAC_CHANNEL_TYPE ChannelType) { - return ((ChannelType >= VtUtf8) && (ChannelType <= Raw)); + /* Check if the type is valid */ + return ((ChannelType >= VtUtf8) && (ChannelType <= Raw)); } BOOLEAN -ChannelIsEqual( - IN PSAC_CHANNEL Channel, - IN PSAC_CHANNEL_ID ChannelId - ) +NTAPI +ChannelIsEqual(IN PSAC_CHANNEL Channel, + IN PSAC_CHANNEL_ID ChannelId) { - return IsEqualGUIDAligned( - &Channel->ChannelId.ChannelGuid, - &ChannelId->ChannelGuid); + /* Check if the GUIDs match */ + return IsEqualGUIDAligned(&Channel->ChannelId.ChannelGuid, + &ChannelId->ChannelGuid); } NTSTATUS -ChannelInitializeVTable( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelDereferenceHandles(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER(Channel); + + /* Clear the data event */ + if (Channel->HasNewDataEvent) + { + ChannelUninitializeEvent(Channel, + HasNewDataEvent, + SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT); + } + + /* Clear the close event */ + if (Channel->CloseEvent) + { + ChannelUninitializeEvent(Channel, + CloseEvent, + SAC_CHANNEL_FLAG_CLOSE_EVENT); + } + + /* Clear the lock event */ + if (Channel->LockEvent) + { + ChannelUninitializeEvent(Channel, + LockEvent, + SAC_CHANNEL_FLAG_LOCK_EVENT); + } + + /* Clear the redraw event */ + if (Channel->RedrawEvent) + { + ChannelUninitializeEvent(Channel, + RedrawEvent, + SAC_CHANNEL_FLAG_REDRAW_EVENT); + } + + /* All done */ + return STATUS_SUCCESS; } NTSTATUS -ChannelDereferenceHandles( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelDestroy(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER(Channel); + + /* Same thing as dereferencing all the handles */ + return ChannelDereferenceHandles(Channel); } NTSTATUS -ChannelDestroy( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelOWrite(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize) { - CHECK_PARAMETER(Channel); - - return ChannelDereferenceHandles(Channel); + NTSTATUS Status; + CHECK_PARAMETER3(BufferSize < SAC_OBUFFER_SIZE); + + /* While holding the output lock, write to the output buffer */ + ChannelLockOBuffer(Channel); + Status = Channel->ChannelOutputWrite(Channel, Buffer, BufferSize); + ChannelUnlockOBuffer(Channel); + return Status; } NTSTATUS -ChannelOWrite( - IN PSAC_CHANNEL Channel, - IN PWCHAR Buffer, - IN ULONG BufferSize - ) +NTAPI +ChannelOFlush(IN PSAC_CHANNEL Channel) { - NTSTATUS Status; - - CHECK_PARAMETER3(BufferSize < SAC_OBUFFER_SIZE); + NTSTATUS Status; - ChannelLockOBuffer(Channel); - - Status = Channel->OBufferWrite(Channel, Buffer, BufferSize); - - ChannelUnlockOBuffer(Channel); - - return Status; + /* While holding the output lock, flush to the output buffer */ + ChannelLockOBuffer(Channel); + Status = Channel->ChannelOutputFlush(Channel); + ChannelUnlockOBuffer(Channel); + return Status; } NTSTATUS -ChannelOFlush( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelIWrite(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize) { - NTSTATUS Status; - - ChannelLockOBuffer(Channel); + NTSTATUS Status; - Status = Channel->OBufferFlush(Channel); - - ChannelUnlockOBuffer(Channel); - - return Status; + /* Write into the input buffer while holding the lock */ + ChannelLockIBuffer(Channel); + Status = Channel->ChannelInputWrite(Channel, Buffer, BufferSize); + ChannelUnlockIBuffer(Channel); + return Status; } NTSTATUS -ChannelIWrite( - IN PSAC_CHANNEL Channel, - IN PWCHAR Buffer, - IN ULONG BufferSize - ) +NTAPI +ChannelIRead(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + IN OUT PULONG ResultBufferSize) { - NTSTATUS Status; + NTSTATUS Status; - ChannelLockIBuffer(Channel); - - Status = Channel->IBufferWrite(Channel, Buffer, BufferSize); - - ChannelUnlockIBuffer(Channel); - - return Status; + /* Read the input buffer while holding the lock */ + ChannelLockIBuffer(Channel); + Status = Channel->ChannelInputRead(Channel, + Buffer, + BufferSize, + ResultBufferSize); + ChannelUnlockIBuffer(Channel); + return Status; } -ULONG -ChannelIRead( - IN PSAC_CHANNEL Channel, - PWCHAR Buffer, - ULONG BufferSize, - OUT PULONG ResultBufferSize - ) +UCHAR +NTAPI +ChannelIReadLast(IN PSAC_CHANNEL Channel) { - NTSTATUS Status; - - ChannelLockIBuffer(Channel); + UCHAR LastChar; - Status = Channel->IBufferRead(Channel, Buffer, BufferSize, ResultBufferSize); - - ChannelUnlockIBuffer(Channel); - - return Status; -} - -NTSTATUS -ChannelIReadLast( - IN PSAC_CHANNEL Channel - ) -{ - NTSTATUS Status; - - ChannelLockIBuffer(Channel); - - Status = Channel->IBufferReadLast(Channel); - - ChannelUnlockIBuffer(Channel); - - return Status; + /* Read the last character while holding the lock */ + ChannelLockIBuffer(Channel); + LastChar = Channel->ChannelInputReadLast(Channel); + ChannelUnlockIBuffer(Channel); + return LastChar; } ULONG -ChannelIBufferLength( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelIBufferLength(IN PSAC_CHANNEL Channel) { - NTSTATUS Length; + ULONG Length; - ChannelLockOBuffer(Channel); - - Length = Channel->IBufferLength(Channel); - - ChannelUnlockOBuffer(Channel); - - return Length; -} - -NTSTATUS -ChannelGetName( - IN PSAC_CHANNEL Channel, - OUT PWCHAR *Name - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelSetName( - IN PSAC_CHANNEL Channel, - IN PWCHAR Name - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelGetDescription( - IN PSAC_CHANNEL Channel, - OUT PWCHAR *Description - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelSetDescription( - IN PSAC_CHANNEL Channel, - IN PWCHAR Description - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelSetStatus( - IN PSAC_CHANNEL Channel, - IN SAC_CHANNEL_STATUS ChannelStatus - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelGetStatus( - IN PSAC_CHANNEL Channel, - OUT PSAC_CHANNEL_STATUS ChannelStatus - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ChannelGetApplicationType( - IN PSAC_CHANNEL Channel, - OUT PGUID ApplicationType - ) -{ - return STATUS_NOT_IMPLEMENTED; + /* Get the input buffer length while holding the lock */ + ChannelLockOBuffer(Channel); + Length = Channel->ChannelInputBufferLength(Channel); + ChannelUnlockOBuffer(Channel); + return Length; } NTSTATUS NTAPI -ChannelSetLockEvent( - IN PSAC_CHANNEL Channel - ) +ChannelSetRedrawEvent(IN PSAC_CHANNEL Channel) { - NTSTATUS Status; - - ChannelSetEvent(Channel, LockEvent); - - return Status; + NTSTATUS Status; + + /* Set the event */ + ChannelSetEvent(Channel, RedrawEvent); + return Status; } NTSTATUS NTAPI -ChannelSetRedrawEvent( - IN PSAC_CHANNEL Channel - ) +ChannelSetLockEvent(IN PSAC_CHANNEL Channel) { - NTSTATUS Status; + NTSTATUS Status; - ChannelSetEvent(Channel, RedrawEvent); - - return Status; + /* Set the event */ + ChannelSetEvent(Channel, LockEvent); + return Status; } NTSTATUS -ChannelClearRedrawEvent( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelClearRedrawEvent(IN PSAC_CHANNEL Channel) { - NTSTATUS Status; - - ChannelClearEvent(Channel, RedrawEvent); - - return Status; + NTSTATUS Status; + + /* Clear the event */ + ChannelClearEvent(Channel, RedrawEvent); + return Status; } NTSTATUS -ChannelHasRedrawEvent( - IN PSAC_CHANNEL Channel, - OUT PBOOLEAN Present - ) +NTAPI +ChannelHasRedrawEvent(IN PSAC_CHANNEL Channel, + OUT PBOOLEAN Present) { - CHECK_PARAMETER1(Channel); - CHECK_PARAMETER2(Present); - - *Present = Channel->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT; - - return STATUS_SUCCESS; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Present); + + /* Return if the flag is set */ + *Present = Channel->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelGetStatus(IN PSAC_CHANNEL Channel, + OUT PSAC_CHANNEL_STATUS ChannelStatus) +{ + CHECK_PARAMETER1(Channel); + + /* Read the status while holding the attribute lock */ + ChannelLockAttributes(Channel); + *ChannelStatus = Channel->ChannelStatus; + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelSetStatus(IN PSAC_CHANNEL Channel, + IN SAC_CHANNEL_STATUS ChannelStatus) +{ + CHECK_PARAMETER1(Channel); + + /* Read the status while holding the attribute lock */ + ChannelLockAttributes(Channel); + Channel->ChannelStatus = ChannelStatus; + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; } BOOLEAN -ChannelIsActive( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelIsActive(IN PSAC_CHANNEL Channel) { - SAC_CHANNEL_STATUS ChannelStatus; + SAC_CHANNEL_STATUS ChannelStatus; + BOOLEAN IsActive; - if (!NT_SUCCESS(ChannelGetStatus(Channel, &ChannelStatus))) return FALSE; + /* Get the status */ + if (!NT_SUCCESS(ChannelGetStatus(Channel, &ChannelStatus))) + { + /* We couldn't even do that, assume it's inactive */ + IsActive = FALSE; + } + else + { + /* Check if the status shows activity */ + IsActive = (ChannelStatus == Active); + } - return (ChannelStatus == Active); + /* Return the state */ + return IsActive; } BOOLEAN -ChannelIsClosed( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelIsClosed(IN PSAC_CHANNEL Channel) { - return FALSE; + SAC_CHANNEL_STATUS ChannelStatus; + BOOLEAN IsClosed; + + /* Get the status */ + if (!NT_SUCCESS(ChannelGetStatus(Channel, &ChannelStatus))) + { + /* We couldn't even do that, assume it's inactive */ + IsClosed = FALSE; + } + else + { + /* Check if the status shows activity */ + IsClosed = ((ChannelStatus == Inactive) && + (Channel->ChannelHasNewOBufferData)); + } + + /* Return the state */ + return IsClosed; } NTSTATUS -ChannelCreate( - IN PSAC_CHANNEL Channel, - IN PSAC_CHANNEL_ATTRIBUTES Attributes, - IN SAC_CHANNEL_ID ChannelId - ) +NTAPI +ChannelGetName(IN PSAC_CHANNEL Channel, + OUT PWCHAR *Name) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Name); + + /* Allocate space to hold the name */ + *Name = SacAllocatePool(sizeof(Channel->NameBuffer), GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(*Name); + + /* Lock the attributes while we copy the name */ + ChannelLockAttributes(Channel); + + /* Copy the name and null-terminate it */ + ASSERT(((wcslen(Channel->NameBuffer) + 1) * sizeof(WCHAR)) <= ((64 + 1) * sizeof(WCHAR))); + wcsncpy(*Name, Channel->NameBuffer, RTL_NUMBER_OF(Channel->NameBuffer)); // bug + (*Name)[SAC_CHANNEL_NAME_SIZE] = UNICODE_NULL; + + /* Release the lock and return */ + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; } NTSTATUS -ChannelClose( - IN PSAC_CHANNEL Channel - ) +NTAPI +ChannelSetName(IN PSAC_CHANNEL Channel, + IN PWCHAR Name) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Name); + + /* Lock the attributes while we copy the name */ + ChannelLockAttributes(Channel); + + /* Copy the name and null-terminate it */ + ASSERT(((wcslen(Name) + 1) * sizeof(WCHAR)) <= ((64 + 1) * sizeof(WCHAR))); + wcsncpy(Channel->NameBuffer, Name, RTL_NUMBER_OF(Channel->NameBuffer)); // bug + Channel->NameBuffer[SAC_CHANNEL_NAME_SIZE] = UNICODE_NULL; + + /* Release the lock and return */ + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; } + +NTSTATUS +NTAPI +ChannelGetDescription(IN PSAC_CHANNEL Channel, + IN PWCHAR* Description) +{ + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Description); + + /* Allocate space to hold the description */ + *Description = SacAllocatePool(sizeof(Channel->DescriptionBuffer), GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(*Description); + + /* Lock the attributes while we copy the name */ + ChannelLockAttributes(Channel); + + /* Copy the name and null-terminate it */ + ASSERT(((wcslen(Channel->DescriptionBuffer) + 1) * sizeof(WCHAR)) <= ((256 + 1) * sizeof(WCHAR))); + wcsncpy(*Description, Channel->DescriptionBuffer, RTL_NUMBER_OF(Channel->DescriptionBuffer)); // bug + (*Description)[SAC_CHANNEL_DESCRIPTION_SIZE] = UNICODE_NULL; + + /* Release the lock and return */ + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelSetDescription(IN PSAC_CHANNEL Channel, + IN PWCHAR Description) +{ + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Description); + + /* Lock the attributes while we copy the name */ + ChannelLockAttributes(Channel); + + /* Copy the name and null-terminate it */ + ASSERT(((wcslen(Description) + 1) * sizeof(WCHAR)) <= ((64 + 1) * sizeof(WCHAR))); + wcsncpy(Channel->DescriptionBuffer, Description, RTL_NUMBER_OF(Channel->DescriptionBuffer)); // bug + Channel->DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE] = UNICODE_NULL; + + /* Release the lock and return */ + ChannelUnlockAttributes(Channel); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelGetApplicationType(IN PSAC_CHANNEL Channel, + OUT PGUID ApplicationType) +{ + CHECK_PARAMETER1(Channel); + + /* Read the application type GUID */ + ChannelLockAttributes(Channel); + *ApplicationType = Channel->ApplicationType; + ChannelUnlockAttributes(Channel); + + /* Always return success */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelInitializeVTable(IN PSAC_CHANNEL Channel) +{ + /* What kind of channel is this? */ + switch (Channel->ChannelType) + { + case VtUtf8: + /* FIXME: TODO */ + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; + + case Cmd: + /* FIXME: TODO */ + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; + + case Raw: + + /* Setup the calls for a raw channel */ + Channel->ChannelCreate = RawChannelCreate; + Channel->ChannelDestroy = RawChannelDestroy; + Channel->ChannelOutputFlush = RawChannelOFlush; + Channel->ChannelOutputEcho = RawChannelOEcho; + Channel->ChannelOutputWrite = RawChannelOWrite; + Channel->ChannelOutputRead = RawChannelORead; + Channel->ChannelInputWrite = RawChannelIWrite; + Channel->ChannelInputRead = RawChannelIRead; + Channel->ChannelInputReadLast = RawChannelIReadLast; + Channel->ChannelInputBufferIsFull = RawChannelIBufferIsFull; + Channel->ChannelInputBufferLength = RawChannelIBufferLength; + break; + + default: + /* Unsupported channel type */ + return STATUS_INVALID_PARAMETER; + } + + /* If we got here, the channel was supported */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ChannelCreate(IN PSAC_CHANNEL Channel, + IN PSAC_CHANNEL_ATTRIBUTES Attributes, + IN SAC_CHANNEL_ID ChannelId) +{ + NTSTATUS Status; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Attributes); + + /* If a close event is being passed in, it must exist, and vice-versa */ + if (Attributes->Flag & SAC_CHANNEL_FLAG_CLOSE_EVENT) + { + CHECK_PARAMETER(Attributes->CloseEvent != NULL); + } + else + { + CHECK_PARAMETER(Attributes->CloseEvent == NULL); + } + + /* If a new data event is being passed in, it must exist, and vice-versa */ + if (Attributes->Flag & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) + { + CHECK_PARAMETER(Attributes->HasNewDataEvent != NULL); + } + else + { + CHECK_PARAMETER(Attributes->HasNewDataEvent == NULL); + } + + /* If a lock event is being passed in, it must exist, and vice-versa */ + if (Attributes->Flag & SAC_CHANNEL_FLAG_LOCK_EVENT) + { + CHECK_PARAMETER(Attributes->LockEvent != NULL); + } + else + { + CHECK_PARAMETER(Attributes->LockEvent == NULL); + } + + /* If a redraw event is being passed in, it must exist, and vice-versa */ + if (Attributes->Flag & SAC_CHANNEL_FLAG_REDRAW_EVENT) + { + CHECK_PARAMETER(Attributes->RedrawEvent != NULL); + } + else + { + CHECK_PARAMETER(Attributes->RedrawEvent == NULL); + } + + /* Initialize the channel structure */ + RtlZeroMemory(Channel, sizeof(SAC_CHANNEL)); + Channel->ChannelId = ChannelId; + Channel->ChannelType = Attributes->ChannelType; + Channel->Flags = Attributes->Flag; + if (Attributes->Flag & SAC_CHANNEL_FLAG_APPLICATION) + { + Channel->ApplicationType = Attributes->ChannelId; + } + + /* Initialize all the locks and events */ + SacInitializeLock(&Channel->ChannelAttributeLock); + SacInitializeLock(&Channel->ChannelOBufferLock); + SacInitializeLock(&Channel->ChannelIBufferLock); + ChannelInitializeEvent(Channel, Attributes, CloseEvent); + ChannelInitializeEvent(Channel, Attributes, HasNewDataEvent); + ChannelInitializeEvent(Channel, Attributes, LockEvent); + ChannelInitializeEvent(Channel, Attributes, RedrawEvent); + + /* Set the name and description */ + ChannelSetName(Channel, Attributes->NameBuffer); + ChannelSetDescription(Channel, Attributes->DescriptionBuffer); + + /* Initialize the function table for the type of channel this is */ + Status = ChannelInitializeVTable(Channel); + if (!NT_SUCCESS(Status)) + { + /* This is critical */ + SAC_DBG(SAC_DBG_INIT, "SAC Create Channel :: Failed to initialize vtable\n"); + goto FailChannel; + } + + /* Now call the channel specific type constructor */ + Status = Channel->ChannelCreate(Channel); + if (!NT_SUCCESS(Status)) + { + /* This is critical */ + SAC_DBG(SAC_DBG_INIT, "SAC Create Channel :: Failed channel specific initialization\n"); + goto FailChannel; + } + + /* Finally, mark the channel as active */ + ChannelSetStatus(Channel, Active); + return STATUS_SUCCESS; + +FailChannel: + /* Destroy the channel and return the failure code */ + Channel->ChannelDestroy(Channel); + return Status; +} + +NTSTATUS +NTAPI +ChannelClose(IN PSAC_CHANNEL Channel) +{ + NTSTATUS Status; + CHECK_PARAMETER(Channel); + + /* Set the channel inactive */ + ChannelSetStatus(Channel, Inactive); + + /* Set the close event */ + if (Channel->Flags & SAC_CHANNEL_FLAG_CLOSE_EVENT) + { + ChannelSetEvent(Channel, CloseEvent); + } + + /* Close all the handles */ + Status = ChannelDereferenceHandles(Channel); + return Status; +} + diff --git a/drivers/sac/driver/concmd.c b/drivers/sac/driver/concmd.c index 42b87ca2795..76d6edbfe47 100644 --- a/drivers/sac/driver/concmd.c +++ b/drivers/sac/driver/concmd.c @@ -1,18 +1,75 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/concmd.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/concmd.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +PWCHAR GlobalBuffer; +ULONG GlobalBufferSize; + +/* FUNCTIONS *****************************************************************/ + +VOID +NTAPI +DoRebootCommand(IN BOOLEAN Reboot) +{ + LARGE_INTEGER Timeout, TickCount; + NTSTATUS Status; + KEVENT Event; + SAC_DBG(1, "SAC DoRebootCommand: Entering.\n"); + + /* Get the current time now, and setup a timeout in 1 second */ + KeQueryTickCount(&TickCount); + Timeout.QuadPart = TickCount.QuadPart / (10000000 / KeQueryTimeIncrement()); + + /* Check if the timeout is small enough */ + if (Timeout.QuadPart < 60 ) + { + /* Show the prompt */ + ConMgrSimpleEventMessage(Reboot ? + SAC_RESTART_PROMPT : SAC_SHUTDOWN_PROMPT, + TRUE); + + /* Do the wait */ + KeInitializeEvent(&Event, SynchronizationEvent, 0); + Timeout.QuadPart = -10000000 * (60 - Timeout.LowPart); + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &Timeout); + } + + /* Do a shutdown or a reboot, based on the request */ + Status = NtShutdownSystem(Reboot ? ShutdownReboot : ShutdownPowerOff); + + /* Check if anyone in the command channel already allocated this */ + if (!GlobalBuffer) + { + /* Allocate it */ + GlobalBuffer = SacAllocatePool(PAGE_SIZE, GLOBAL_BLOCK_TAG); + if (!GlobalBuffer) + { + /* We need the global buffer, bail out without it*/ + SacPutSimpleMessage(SAC_OUT_OF_MEMORY_PROMPT); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting (1).\n"); + return; + } + + /* Set the size of the buffer */ + GlobalBufferSize = PAGE_SIZE; + } + + /* We came back from a reboot, this doesn't make sense, tell the user */ + SacPutSimpleMessage(Reboot ? SAC_RESTART_FAIL_PROMPT : SAC_SHUTDOWN_FAIL_PROMPT); + swprintf(GlobalBuffer, GetMessage(SAC_FAIL_PROMPT), Status); + SacPutString(GlobalBuffer); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting.\n"); +} NTSTATUS GetTListInfo( @@ -122,14 +179,6 @@ DoLimitMemoryCommand( } -VOID -DoRebootCommand( - IN BOOLEAN Reboot - ) -{ - -} - VOID DoCrashCommand( VOID diff --git a/drivers/sac/driver/conmgr.c b/drivers/sac/driver/conmgr.c index a01819394af..b012cad03f7 100644 --- a/drivers/sac/driver/conmgr.c +++ b/drivers/sac/driver/conmgr.c @@ -1,191 +1,541 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/conmgr.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/conmgr.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +DEFINE_GUID(PRIMARY_SAC_CHANNEL_APPLICATION_GUID, + 0x63D02270, + 0x8AA4, + 0x11D5, + 0xBC, 0xCF, 0x80, 0x6D, 0x61, 0x72, 0x69, 0x6F); -NTSTATUS -ConMgrShutdown( - VOID) +LONG CurrentChannelRefCount; +KMUTEX CurrentChannelLock; + +PSAC_CHANNEL CurrentChannel; +PSAC_CHANNEL SacChannel; + +ULONG ExecutePostConsumerCommand; +PSAC_CHANNEL ExecutePostConsumerCommandData; + +/* FUNCTIONS *****************************************************************/ + +VOID +NTAPI +ConMgrSerialPortConsumer(VOID) { - return STATUS_NOT_IMPLEMENTED; -} + NTSTATUS Status; + CHAR Char; + SAC_DBG(0x2000, "SAC TimerDpcRoutine: Entering.\n"); //bug -NTSTATUS -ConMgrDisplayFastChannelSwitchingInterface( - IN PSAC_CHANNEL Channel - ) -{ - return STATUS_NOT_IMPLEMENTED; -} + /* Acquire the manager lock and make sure a channel is selected */ + SacAcquireMutexLock(); + ASSERT(CurrentChannel); -NTSTATUS -ConMgrSetCurrentChannel( - IN PSAC_CHANNEL Channel - ) -{ - return STATUS_NOT_IMPLEMENTED; -} + /* Read whatever came off the serial port */ + for (Status = SerialBufferGetChar(&Char); + NT_SUCCESS(Status); + Status = SerialBufferGetChar(&Char)) + { + /* If nothing came through, bail out */ + if (Status == STATUS_NO_DATA_DETECTED) break; + } -NTSTATUS -ConMgrDisplayCurrentChannel( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ConMgrAdvanceCurrentChannel( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -BOOLEAN -ConMgrIsWriteEnabled( - IN PSAC_CHANNEL Channel - ) -{ - return FALSE; + /* We're done, release the lock */ + SacReleaseMutexLock(); + SAC_DBG(0x2000, "SAC TimerDpcRoutine: Exiting.\n"); //bug } VOID -SacPutString( - IN PWCHAR String - ) +NTAPI +ConMgrWorkerProcessEvents(IN PSAC_DEVICE_EXTENSION DeviceExtension) { + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC WorkerProcessEvents: Entering.\n"); -} + /* Enter the main loop */ + while (TRUE) + { + /* Wait for something to do */ + KeWaitForSingleObject(&DeviceExtension->Event, + Executive, + KernelMode, + FALSE, + NULL); -BOOLEAN -SacPutSimpleMessage( - IN ULONG MessageIndex - ) -{ - return FALSE; -} + /* Consume data off the serial port */ + ConMgrSerialPortConsumer(); + switch (ExecutePostConsumerCommand) + { + case 1: + /* A reboot was sent, do it */ + DoRebootCommand(FALSE); + break; -NTSTATUS -ConMgrChannelOWrite( - IN PSAC_CHANNEL Channel, - IN PVOID WriteBuffer - ) -{ - return STATUS_NOT_IMPLEMENTED; -} + case 2: + /* A close was sent, do it */ + ChanMgrCloseChannel(ExecutePostConsumerCommandData); + ChanMgrReleaseChannel(ExecutePostConsumerCommandData); + break; -NTSTATUS -ConMgrGetChannelCloseMessage( - IN PSAC_CHANNEL Channel, - IN NTSTATUS CloseStatus, - OUT PWCHAR OutputBuffer - ) -{ - return STATUS_NOT_IMPLEMENTED; -} + case 3: + /* A shutdown was sent, do it */ + DoRebootCommand(TRUE); + break; + } -NTSTATUS -ConMgrWriteData( - IN PSAC_CHANNEL Channel, - IN PVOID Buffer, - IN ULONG BufferLength - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ConMgrFlushData( - IN PSAC_CHANNEL Channel - ) -{ - return FALSE; -} - -BOOLEAN -ConMgrIsSacChannel( - IN PSAC_CHANNEL Channel - ) -{ - return FALSE; -} - -NTSTATUS -ConMgrInitialize( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ConMgrResetCurrentChannel( - IN BOOLEAN KeepChannel - ) -{ - return STATUS_NOT_IMPLEMENTED; + /* Clear the serial port consumer state */ + ExecutePostConsumerCommand = 0; + ExecutePostConsumerCommandData = NULL; + } } VOID -ConMgrProcessInputLine( - VOID - ) -{ - -} - -VOID -ConMgrEventMessage( - IN PWCHAR EventMessage, - IN BOOLEAN LockHeld - ) +NTAPI +SacPutString(IN PWCHAR String) { + NTSTATUS Status; + /* Write the string on the main SAC channel */ + Status = ChannelOWrite(SacChannel, + (PCHAR)String, + wcslen(String) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC XmlMgrSacPutString: OWrite failed\n"); + } } BOOLEAN -ConMgrSimpleEventMessage( - IN ULONG MessageIndex, - IN BOOLEAN LockHeld - ) +NTAPI +SacPutSimpleMessage(IN ULONG MessageIndex) { - return FALSE; + PWCHAR MessageBuffer; + BOOLEAN Result; + + /* Get the message */ + MessageBuffer = GetMessage(MessageIndex); + if (MessageBuffer) + { + /* Output it */ + SacPutString(MessageBuffer); + Result = TRUE; + } + else + { + Result = FALSE; + } + + /* All done */ + return Result; } NTSTATUS -ConMgrChannelClose( - IN PSAC_CHANNEL Channel - ) +NTAPI +ConMgrDisplayCurrentChannel(VOID) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + BOOLEAN HasRedraw; + + /* Make sure the lock is held */ + SacAssertMutexLockHeld(); + + /* Check if we can redraw */ + Status = ChannelHasRedrawEvent(CurrentChannel, &HasRedraw); + if (NT_SUCCESS(Status)) + { + /* Enable writes */ + _InterlockedExchange(&CurrentChannel->WriteEnabled, 1); + if (HasRedraw) + { + /* If we can redraw, set the event */ + ChannelSetRedrawEvent(CurrentChannel); + } + + /* Flush the output */ + Status = ChannelOFlush(CurrentChannel); + } + + /* All done, return the status */ + return Status; } NTSTATUS -ConMgrHandleEvent( - IN ULONG EventCode, - IN PSAC_CHANNEL Channel, - OUT PVOID Data - ) +NTAPI +ConMgrWriteData(IN PSAC_CHANNEL Channel, + IN PVOID Buffer, + IN ULONG BufferLength) { - return STATUS_NOT_IMPLEMENTED; + ULONG i; + NTSTATUS Status; + LARGE_INTEGER Interval; + + /* Loop up to 32 times */ + for (i = 0; i < 32; i++) + { + /* Attempt sending the data */ + Status = HeadlessDispatch(HeadlessCmdPutData, Buffer, BufferLength, NULL, NULL); + if (Status != STATUS_UNSUCCESSFUL) break; + + /* Sending the data on the port failed, wait a second... */ + Interval.HighPart = -1; + Interval.LowPart = -100000; + KeDelayExecutionThread(KernelMode, FALSE, &Interval); + } + + /* After 32 attempts it should really have worked... */ + ASSERT(NT_SUCCESS(Status)); + return Status; +} + +NTSTATUS +NTAPI +ConMgrFlushData(IN PSAC_CHANNEL Channel) +{ + /* Nothing to do */ + return STATUS_SUCCESS; +} + +BOOLEAN +NTAPI +ConMgrIsSacChannel(IN PSAC_CHANNEL Channel) +{ + /* Check which channel is active */ + return Channel == SacChannel; +} + +BOOLEAN +NTAPI +ConMgrIsWriteEnabled(IN PSAC_CHANNEL Channel) +{ + /* If the current channel is active, allow writes */ + return ChannelIsEqual(Channel, &CurrentChannel->ChannelId); +} + +NTSTATUS +NTAPI +ConMgrInitialize(VOID) +{ + PWCHAR pcwch; + PSAC_CHANNEL FoundChannel; + SAC_CHANNEL_ATTRIBUTES SacChannelAttributes; + NTSTATUS Status; + + /* Initialize the connection manager lock */ + SacInitializeMutexLock(); + SacAcquireMutexLock(); + + /* Setup the attributes for the raw SAC channel */ + RtlZeroMemory(&SacChannelAttributes, sizeof(SacChannelAttributes)); + SacChannelAttributes.ChannelType = Raw; + + /* Get the right name for it */ + pcwch = GetMessage(SAC_CHANNEL_NAME); + ASSERT(pcwch); + wcsncpy(SacChannelAttributes.NameBuffer, pcwch, SAC_CHANNEL_NAME_SIZE); + SacChannelAttributes.NameBuffer[SAC_CHANNEL_NAME_SIZE] = ANSI_NULL; + + /* Get the right description for it */ + pcwch = GetMessage(SAC_CHANNEL_DESCRIPTION); + ASSERT(pcwch); + wcsncpy(SacChannelAttributes.DescriptionBuffer, pcwch, SAC_CHANNEL_DESCRIPTION_SIZE); + SacChannelAttributes.DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE] = ANSI_NULL; + + /* Set all the right flags */ + SacChannelAttributes.Flag = SAC_CHANNEL_FLAG_APPLICATION | SAC_CHANNEL_FLAG_INTERNAL; + SacChannelAttributes.CloseEvent = NULL; + SacChannelAttributes.HasNewDataEvent = NULL; + SacChannelAttributes.LockEvent = NULL; + SacChannelAttributes.RedrawEvent = NULL; + SacChannelAttributes.ChannelId = PRIMARY_SAC_CHANNEL_APPLICATION_GUID; + + /* Now create it */ + Status = ChanMgrCreateChannel(&SacChannel, &SacChannelAttributes); + if (NT_SUCCESS(Status)) + { + /* Try to get it back */ + Status = ChanMgrGetByHandle(SacChannel->ChannelId, &FoundChannel); + if (NT_SUCCESS(Status)) + { + /* Set it as the current and SAC channel */ + SacChannel = CurrentChannel = FoundChannel; + + /* Diasable writes for now and clear the display */ + _InterlockedExchange(&FoundChannel->WriteEnabled, FALSE); + Status = HeadlessDispatch(HeadlessCmdClearDisplay, NULL, 0, NULL, NULL); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC ConMgrInitialize: Failed dispatch\n"); + } + + /* Display the initial prompt */ + SacPutSimpleMessage(SAC_NEWLINE); + SacPutSimpleMessage(SAC_INIT_STATUS); + SacPutSimpleMessage(SAC_NEWLINE); + SacPutSimpleMessage(SAC_PROMPT); + + /* Display the current channel */ + ConMgrDisplayCurrentChannel(); + } + } + + /* Release the channel lock */ + SacReleaseMutexLock(); + return STATUS_SUCCESS; } VOID -ConMgrWorkerProcessEvents( - IN PSAC_CHANNEL Channel - ) +NTAPI +ConMgrEventMessage(IN PWCHAR EventMessage, + IN BOOLEAN LockHeld) { + /* Acquire the current channel lock if needed */ + if (!LockHeld) SacAcquireMutexLock(); + /* Send out the event message */ + SacPutSimpleMessage(2); + SacPutString(EventMessage); + SacPutSimpleMessage(3); + + /* Release the current channel lock if needed */ + if (!LockHeld) SacReleaseMutexLock(); } + +BOOLEAN +NTAPI +ConMgrSimpleEventMessage(IN ULONG MessageIndex, + IN BOOLEAN LockHeld) +{ + PWCHAR MessageBuffer; + BOOLEAN Result; + + /* Get the message to send out */ + MessageBuffer = GetMessage(MessageIndex); + if (MessageBuffer) + { + /* Send it */ + ConMgrEventMessage(MessageBuffer, LockHeld); + Result = TRUE; + } + else + { + /* It doesn't exist, fail */ + Result = FALSE; + } + + /* Return if the message was sent or not */ + return Result; +} + +NTSTATUS +NTAPI +ConMgrDisplayFastChannelSwitchingInterface(IN PSAC_CHANNEL Channel) +{ + /* FIXME: TODO */ + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +ConMgrSetCurrentChannel(IN PSAC_CHANNEL Channel) +{ + NTSTATUS Status; + BOOLEAN HasRedrawEvent; + + /* Make sure the lock is held */ + SacAssertMutexLockHeld(); + + /* Check if we have a redraw event */ + Status = ChannelHasRedrawEvent(CurrentChannel, &HasRedrawEvent); + if (!NT_SUCCESS(Status)) return Status; + + /* Clear it */ + if (HasRedrawEvent) ChannelClearRedrawEvent(CurrentChannel); + + /* Disable writes on the current channel */ + _InterlockedExchange(&CurrentChannel->WriteEnabled, 0); + + /* Release the current channel */ + Status = ChanMgrReleaseChannel(CurrentChannel); + if (!NT_SUCCESS(Status)) return Status; + + /* Set the new channel and also disable writes on it */ + CurrentChannel = Channel; + _InterlockedExchange(&Channel->WriteEnabled, 0); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ConMgrResetCurrentChannel(IN BOOLEAN KeepChannel) +{ + NTSTATUS Status; + PSAC_CHANNEL Channel; + + /* Make sure the lock is held */ + SacAssertMutexLockHeld(); + + /* Get the current SAC channel */ + Status = ChanMgrGetByHandle(SacChannel->ChannelId, &Channel); + if (NT_SUCCESS(Status)) + { + /* Set this as the current SAC channel*/ + SacChannel = Channel; + Status = ConMgrSetCurrentChannel(Channel); + if (NT_SUCCESS(Status)) + { + /* Check if the caller wants to switch or not */ + if (KeepChannel) + { + /* Nope, keep the same channel */ + Status = ConMgrDisplayCurrentChannel(); + } + else + { + /* Yep, show the switching interface */ + Status = ConMgrDisplayFastChannelSwitchingInterface(CurrentChannel); + } + } + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +ConMgrChannelClose(IN PSAC_CHANNEL Channel) +{ + NTSTATUS Status = STATUS_SUCCESS; + + /* Check if we're in the right channel */ + if (ConMgrIsWriteEnabled(Channel)) + { + /* Yep, reset it */ + Status = ConMgrResetCurrentChannel(FALSE); + ASSERT(NT_SUCCESS(Status)); + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +ConMgrShutdown(VOID) +{ + NTSTATUS Status; + + /* Check if we have a SAC channel */ + if (SacChannel) + { + /* Close it */ + Status = ChannelClose(SacChannel); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC ConMgrShutdown: failed closing SAC channel.\n"); + } + + /* No longer have one */ + SacChannel = NULL; + } + + /* Check if we have a current channel */ + if (CurrentChannel) + { + /* Release it */ + Status = ChanMgrReleaseChannel(CurrentChannel); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC ConMgrShutdown: failed releasing current channel\n"); + } + + /* No longer have one */ + CurrentChannel = NULL; + } + + /* All done */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ConMgrAdvanceCurrentChannel(VOID) +{ + NTSTATUS Status; + ULONG Index; + PSAC_CHANNEL Channel; + + /* Should always be called with the lock held */ + SacAssertMutexLockHeld(); + + /* Get the next active channel */ + Status = ChanMgrGetNextActiveChannel(CurrentChannel, &Index, &Channel); + if (NT_SUCCESS(Status)) + { + /* Set it as the new channel */ + Status = ConMgrSetCurrentChannel(Channel); + if (NT_SUCCESS(Status)) + { + /* Let the user switch to it */ + Status = ConMgrDisplayFastChannelSwitchingInterface(Channel); + } + } + + /* All done */ + return Status; +} + +NTSTATUS +NTAPI +ConMgrChannelOWrite(IN PSAC_CHANNEL Channel, + IN PVOID WriteBuffer) +{ + NTSTATUS Status; + + /* Do the write with the lock held */ + SacAcquireMutexLock(); + Status = STATUS_NOT_IMPLEMENTED;// ChannelOWrite(Channel, WriteBuffer + 24, *(WriteBuffer + 20)); + SacReleaseMutexLock(); + + /* Return back to the caller */ + ASSERT(NT_SUCCESS(Status) || Status == STATUS_NOT_FOUND); + return Status; +} + +NTSTATUS +NTAPI +ConMgrGetChannelCloseMessage(IN PSAC_CHANNEL Channel, + IN NTSTATUS CloseStatus, + OUT PWCHAR OutputBuffer) +{ + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +VOID +NTAPI +ConMgrProcessInputLine(VOID) +{ + ASSERT(FALSE); +} + +NTSTATUS +NTAPI +ConMgrHandleEvent(IN ULONG EventCode, + IN PSAC_CHANNEL Channel, + OUT PVOID Data) +{ + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + diff --git a/drivers/sac/driver/data.c b/drivers/sac/driver/data.c index 42ebd90662d..eee9ce0c7a7 100644 --- a/drivers/sac/driver/data.c +++ b/drivers/sac/driver/data.c @@ -1,58 +1,502 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/data.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/data.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -ULONG SACDebug; +ULONG SACDebug = 0xFFFFFFFF; +BOOLEAN CommandConsoleLaunchingEnabled; +BOOLEAN GlobalDataInitialized; +KMUTEX SACCMDEventInfoMutex; +BOOLEAN IoctlSubmitted; +ULONG ProcessingType; +PKEVENT SACEvent; +HANDLE SACEventHandle; -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ VOID -FreeGlobalData( - VOID - ) +NTAPI +WorkerProcessEvents(IN PSAC_DEVICE_EXTENSION DeviceExtension) { - + /* Call the worker function */ + return ConMgrWorkerProcessEvents(DeviceExtension); } VOID -FreeDeviceData( - IN PDEVICE_OBJECT DeviceObject - ) +NTAPI +WorkerThreadStartUp(IN PVOID Context) { - + /* Call the worker function */ + WorkerProcessEvents((PSAC_DEVICE_EXTENSION)Context); } NTSTATUS -WorkerThreadStartUp( - IN PVOID Context - ) +NTAPI +BuildDeviceAcl(OUT PACL* Dacl) { - return STATUS_NOT_IMPLEMENTED; + /* TODO */ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +CreateDeviceSecurityDescriptor(IN PDEVICE_OBJECT *DeviceObject) +{ + NTSTATUS Status; + PSECURITY_DESCRIPTOR SecurityDescriptor; + BOOLEAN MemoryAllocated = FALSE; + PACL Dacl = NULL; + PVOID ObjectSecurityDescriptor = NULL; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC CreateDeviceSecurityDescriptor: Entering.\n"); + + /* Get the current SD of the device object */ + Status = ObGetObjectSecurity(*DeviceObject, &SecurityDescriptor, &MemoryAllocated); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC: Unable to get security descriptor, error: %x\n", Status); + NT_ASSERT(MemoryAllocated == FALSE); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC CreateDeviceSecurityDescriptor: Exiting with status 0x%x\n", Status); + return Status; + } + + /* Build a DACL for it */ + Status = BuildDeviceAcl(&Dacl); + if (Status >= 0) + { + ASSERT(FALSE); + } + else + { + SAC_DBG(SAC_DBG_INIT, "SAC CreateDeviceSecurityDescriptor : Unable to create Raw ACL, error : %x\n", Status); + goto CleanupPath; + } + +CleanupPath: + /* Release the SD we queried */ + ObReleaseObjectSecurity(SecurityDescriptor, MemoryAllocated); + + /* Free anything else we may have allocated */ + if (ObjectSecurityDescriptor) ExFreePool(ObjectSecurityDescriptor); + if (Dacl) SacFreePool(Dacl); + + /* All done */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC CreateDeviceSecurityDescriptor: Exiting with status 0x%x\n", Status); + return Status; +} + +VOID +NTAPI +FreeGlobalData(VOID) +{ + UNICODE_STRING SymbolicLink; + SAC_DBG(1, "SAC FreeGlobalData: Entering.\n"); + + /* Only free if we allocated */ + if (GlobalDataInitialized) + { + /* Close the SAC event if we had created one */ + if (SACEvent) + { + ZwClose(SACEventHandle); + SACEvent = NULL; + } + + /* Destroy the cached messages */ + TearDownGlobalMessageTable(); + + /* Delete the Win32 symbolic link */ + RtlInitUnicodeString(&SymbolicLink, L"\\DosDevices\\SAC"); + IoDeleteSymbolicLink(&SymbolicLink); + + /* Tear down connections */ + ConMgrShutdown(); + + /* Tear down channels */ + ChanMgrShutdown(); + + /* Free the serial port buffer */ + if (SerialPortBuffer) SacFreePool(SerialPortBuffer); + + /* Free cached machine information */ + FreeMachineInformation(); + + /* Cleanup the custom heap allocator */ + FreeMemoryManagement(); + + /* We're back to a virgin state */ + GlobalDataInitialized = FALSE; + } + + /* All done */ + SAC_DBG(1, "SAC FreeGlobalData: Exiting.\n"); +} + +VOID +NTAPI +FreeDeviceData(IN PDEVICE_OBJECT DeviceObject) +{ + PSAC_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + KIRQL OldIrql; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC FreeDeviceData: Entering.\n"); + + /* Get the device extension and see how far we had gotten */ + DeviceExtension = (PSAC_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + if ((GlobalDataInitialized) && (DeviceExtension->Initialized)) + { + /* Attempt to rundown while holding the lock */ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + while (DeviceExtension->RundownInProgress) + { + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC FreeDeviceData: Waiting....\n"); + + /* Initiate and wait for rundown */ + KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, 0); + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent, + Executive, + KernelMode, + FALSE, + NULL); + ASSERT(Status == STATUS_SUCCESS); + + /* Re-acquire the lock and check if rundown is done */ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + } + } + + /* Now set the rundown flag while we cancel the timer */ + DeviceExtension->RundownInProgress = TRUE; + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + + /* Cancel it */ + KeCancelTimer(&DeviceExtension->Timer); + + /* Reacquire the lock*/ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + DeviceExtension->RundownInProgress = FALSE; + + /* Now do the last rundown attempt, we should be the only ones here */ + KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, 0); + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + KeSetEvent(&DeviceExtension->Event, DeviceExtension->PriorityBoost, 0); + Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent, + Executive, + KernelMode, + FALSE, + NULL); + ASSERT(Status == STATUS_SUCCESS); + + /* We no longer care about shutdown */ + IoUnregisterShutdownNotification(DeviceObject); + + /* We are now fully uninitialized */ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + DeviceExtension->Initialized = FALSE; + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC FreeDeviceData: Exiting.\n"); } BOOLEAN -InitializeDeviceData( - IN PDEVICE_OBJECT DeviceObject - ) +NTAPI +InitializeDeviceData(IN PDEVICE_OBJECT DeviceObject) { - return FALSE; + PSAC_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + BOOLEAN EnableData; + ULONG PriorityValue; + NTSTATUS Status; + LARGE_INTEGER DueTime; + PWCHAR Message; + PAGED_CODE(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); + + /* If we already did this, bail out */ + if (DeviceExtension->Initialized) goto SuccessExit; + + /* Setup the DO flags */ + DeviceObject->Flags |= DO_DIRECT_IO; + DeviceObject->StackSize = 16; + + /* Setup the device extension */ + DeviceExtension->DeviceObject = DeviceObject; + DeviceExtension->PriorityBoost = IO_SERIAL_INCREMENT; + DeviceExtension->PriorityFail = 0; + DeviceExtension->RundownInProgress = 0; + + /* Initialize locks, events, timers, DPCs, etc... */ + KeInitializeTimer(&DeviceExtension->Timer); + KeInitializeDpc(&DeviceExtension->Dpc, TimerDpcRoutine, DeviceExtension); + KeInitializeSpinLock(&DeviceExtension->Lock); + KeInitializeEvent(&DeviceExtension->Event, SynchronizationEvent, 0); + InitializeListHead(&DeviceExtension->List); + + /* Attempt to enable HDL support */ + EnableData = TRUE; + Status = HeadlessDispatch(HeadlessCmdEnableTerminal, + &EnableData, + sizeof(EnableData), + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + /* Bail out if we couldn't even get this far */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (1) with status FALSE\n"); + return FALSE; + } + + /* Remember which process we started in */ + DeviceExtension->Process = IoGetCurrentProcess(); + + /* Protect the device against non-admins */ + Status = CreateDeviceSecurityDescriptor(&DeviceExtension->DeviceObject); + if (!NT_SUCCESS(Status)) + { + /* Write down why we failed */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (2) with status FALSE\n"); + + /* Disable the HDL terminal on failure */ + EnableData = FALSE; + Status = HeadlessDispatch(HeadlessCmdEnableTerminal, + &EnableData, + sizeof(EnableData), + NULL, + NULL); + if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n"); + + /* Bail out */ + return FALSE; + } + + /* Create the worker thread */ + Status = PsCreateSystemThread(&DeviceExtension->WorkerThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + NULL, + WorkerThreadStartUp, + DeviceExtension); + if (!NT_SUCCESS(Status)) + { + /* Write down why we failed */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (3) with status FALSE\n"); + + /* Disable the HDL terminal on failure */ + EnableData = FALSE; + Status = HeadlessDispatch(HeadlessCmdEnableTerminal, + &EnableData, + sizeof(EnableData), + NULL, + NULL); + if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n"); + + /* Bail out */ + return FALSE; + } + + /* Set the priority of our thread to highest */ + PriorityValue = HIGH_PRIORITY; + Status = NtSetInformationThread(DeviceExtension->WorkerThreadHandle, + ThreadPriority, + &PriorityValue, + sizeof(PriorityValue)); + if (!NT_SUCCESS(Status)) + { + /* For debugging, write down why we failed */ + SAC_DBG(1, "Exiting (6) with status FALSE\n"); + DeviceExtension->PriorityFail = TRUE; + + /* Initialize rundown and wait for the thread to do it */ + KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, 0); + KeSetEvent(&DeviceExtension->Event, DeviceExtension->PriorityBoost, 0); + Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent, + Executive, + KernelMode, + FALSE, + NULL); + ASSERT(Status == STATUS_SUCCESS); + + /* Disable the HDL terminal on failure */ + EnableData = FALSE; + Status = HeadlessDispatch(HeadlessCmdEnableTerminal, + &EnableData, + sizeof(EnableData), + NULL, + 0); + if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n"); + + /* Bail out */ + return FALSE; + } + + /* The first "packet" is the machine information in XML... */ + Status = TranslateMachineInformationXML(&Message, NULL); + if (NT_SUCCESS(Status)) + { + /* Go ahead and send it */ + UTF8EncodeAndSend(L"\r\n"); + UTF8EncodeAndSend(Message); + + /* Free the temporary buffer */ + SacFreePool(Message); + } + + /* Finally, initialize the I/O Manager */ + Status = ConMgrInitialize(); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Set the timer. Once this is done, the device is initialized */ + DueTime.QuadPart = -4000; + KeSetTimerEx(&DeviceExtension->Timer, DueTime, 4, &DeviceExtension->Dpc); + DeviceExtension->Initialized = TRUE; + +SuccessExit: + /* Success path -- everything worked */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status TRUE\n"); + return TRUE; } BOOLEAN -InitializeGlobalData( - IN PUNICODE_STRING RegistryPath, - IN PDRIVER_OBJECT DriverObject - ) +NTAPI +InitializeGlobalData(IN PUNICODE_STRING RegistryPath, + IN PDRIVER_OBJECT DriverObject) { - return FALSE; + NTSTATUS Status; + UNICODE_STRING LinkName; + UNICODE_STRING DeviceName; + UNICODE_STRING EventName; + PAGED_CODE(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); + + /* If we already did this, bail out */ + if (!GlobalDataInitialized) goto SuccessExit; + + /* Setup the symbolic link for Win32 support */ + RtlInitUnicodeString(&LinkName, L"\\DosDevices\\SAC"); + RtlInitUnicodeString(&DeviceName, L"\\Device\\SAC"); + Status = IoCreateSymbolicLink(&LinkName, &DeviceName); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Initialize the internal heap manager */ + if (!InitializeMemoryManagement()) + { + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status FALSE\n"); + return FALSE; + } + + /* Preload the messages in memory */ + Status = PreloadGlobalMessageTable(DriverObject->DriverStart); + if (!NT_SUCCESS(Status)) + { + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_INIT, "unable to pre-load message table: %X\n", Status); + return FALSE; + } + + /* Check if the administrator enabled this */ + Status = GetCommandConsoleLaunchingPermission(&CommandConsoleLaunchingEnabled); + if (!NT_SUCCESS(Status)) + { + /* Is it enabled? */ + if (CommandConsoleLaunchingEnabled) + { + /* Set the service start type to the correct value */ + Status = ImposeSacCmdServiceStartTypePolicy(); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "failed ImposeSacCmdServiceStartTypePolicy: %X\n", Status); + } + } + + /* We're going to keep going with the default */ + SAC_DBG(SAC_DBG_INIT, "failed GetCommandConsoleLaunchingPermission: %X\n", Status); + } + + /* Allocate the UTF-8 Conversion Buffer */ + Utf8ConversionBuffer = SacAllocatePool(Utf8ConversionBufferSize, GLOBAL_BLOCK_TAG); + if (!Utf8ConversionBuffer) + { + /* Handle failure case */ + TearDownGlobalMessageTable(); + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_INIT, "unable to allocate memory for UTF8 translation\n"); + return FALSE; + } + + /* Initialize the channel manager */ + Status = ChanMgrInitialize(); + if (!NT_SUCCESS(Status)) + { + /* Handle failure case */ + SacFreePool(Utf8ConversionBuffer); + TearDownGlobalMessageTable(); + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_INIT, "Failed to create SAC Channel\n"); + return FALSE; + } + + /* Allocate the serial port buffer */ + SerialPortBuffer = SacAllocatePool(SAC_SERIAL_PORT_BUFFER_SIZE, GLOBAL_BLOCK_TAG); + if (!SerialPortBuffer) + { + /* Handle failure case */ + SacFreePool(Utf8ConversionBuffer); + TearDownGlobalMessageTable(); + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_INIT, "Failed to allocate Serial Port Buffer\n"); + return FALSE; + } + + /* Zero it out */ + RtlZeroMemory(SerialPortBuffer, SAC_SERIAL_PORT_BUFFER_SIZE); + + /* Initialize command events. After this, driver data is good to go */ + KeInitializeMutex(&SACCMDEventInfoMutex, FALSE); + InitializeCmdEventInfo(); + GlobalDataInitialized = TRUE; + ProcessingType = 0; + IoctlSubmitted = 0; + + /* Create the SAC event */ + RtlInitUnicodeString(&EventName, L"\\SACEvent"); + SACEvent = IoCreateSynchronizationEvent(&EventName, &SACEventHandle); + if (!SACEvent) + { + /* Handle failure case */ + SacFreePool(Utf8ConversionBuffer); + TearDownGlobalMessageTable(); + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with event NULL\n"); + return FALSE; + } + + /* Cache machine information */ + InitializeMachineInformation(); + + /* Register it */ + Status = RegisterBlueScreenMachineInformation(); + if (!NT_SUCCESS(Status)) + { + /* Handle failure case */ + SacFreePool(Utf8ConversionBuffer); + TearDownGlobalMessageTable(); + IoDeleteSymbolicLink(&LinkName); + SAC_DBG(SAC_DBG_INIT, "Failed to register blue screen machine info\n"); + return FALSE; + } + +SuccessExit: + /* Success path -- everything worked */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status TRUE\n"); + return TRUE; } + diff --git a/drivers/sac/driver/dispatch.c b/drivers/sac/driver/dispatch.c index 58ffaca4115..1af10f57d50 100644 --- a/drivers/sac/driver/dispatch.c +++ b/drivers/sac/driver/dispatch.c @@ -1,88 +1,90 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/dispatch.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/dispatch.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ NTSTATUS NTAPI -DispatchDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ) +DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - return STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -DispatchShutdownControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ) +NTAPI +DispatchShutdownControl(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - return STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -DispatchCreate( - IN PSAC_DEVICE_EXTENSION DeviceExtension, - IN PIRP Irp - ) +NTAPI +DispatchCreate(IN PSAC_DEVICE_EXTENSION DeviceExtension, + IN PIRP Irp) { - return STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -DispatchClose( - IN PSAC_DEVICE_EXTENSION DeviceExtension, - IN PIRP Irp - ) +NTAPI +DispatchClose(IN PSAC_DEVICE_EXTENSION DeviceExtension, + IN PIRP Irp) { - return STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -Dispatch( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ) +NTAPI +Dispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -WorkerProcessEvents( - IN PSAC_CHANNEL Channel - ) -{ - return STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } VOID -TimerDpcRoutine( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2 - ) +NTAPI +TimerDpcRoutine(IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) { } VOID -UnloadHandler( - IN PDRIVER_OBJECT DriverObject - ) +NTAPI +UnloadHandler(IN PDRIVER_OBJECT DriverObject) { + PDEVICE_OBJECT DeviceObject, NextDevice; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC UnloadHandler: Entering.\n"); + /* Go overy ever device part of the driver */ + DeviceObject = DriverObject->DeviceObject; + while (DeviceObject) + { + /* Free and delete the information about this device */ + NextDevice = DeviceObject->NextDevice; + FreeDeviceData(DeviceObject); + IoDeleteDevice(DeviceObject); + + /* Move on to the next one */ + DeviceObject = NextDevice; + } + + /* Free the driver data and exit */ + FreeGlobalData(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC UnloadHandler: Exiting.\n"); } diff --git a/drivers/sac/driver/init.c b/drivers/sac/driver/init.c index 0542d1091da..e0f0a4588a5 100644 --- a/drivers/sac/driver/init.c +++ b/drivers/sac/driver/init.c @@ -1,94 +1,94 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/init.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/init.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ NTSTATUS NTAPI -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) +DriverEntry(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) { - HEADLESS_RSP_QUERY_INFO HeadlessInformation; - ULONG InfoSize; - NTSTATUS Status; - UNICODE_STRING DriverName; - PDEVICE_OBJECT DeviceObject; - PSAC_DEVICE_EXTENSION DeviceExtension; - PAGED_CODE(); + HEADLESS_RSP_QUERY_INFO HeadlessInformation; + ULONG InfoSize = sizeof(HeadlessInformation); + NTSTATUS Status; + UNICODE_STRING DriverName; + PDEVICE_OBJECT DeviceObject; + PSAC_DEVICE_EXTENSION DeviceExtension; + PAGED_CODE(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); + /* Check if EMS is enabled in the kernel */ + HeadlessDispatch(HeadlessCmdQueryInformation, + NULL, + 0, + &HeadlessInformation, + &InfoSize); + if ((HeadlessInformation.Serial.TerminalType != HeadlessUndefinedPortType) && + ((HeadlessInformation.Serial.TerminalType != HeadlessSerialPort) || + (HeadlessInformation.Serial.TerminalAttached))) + { + /* It is, so create the device */ + RtlInitUnicodeString(&DriverName, L"\\Device\\SAC"); + Status = IoCreateDevice(DriverObject, + sizeof(SAC_DEVICE_EXTENSION), + &DriverName, + FILE_DEVICE_UNKNOWN, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &DeviceObject); + if (NT_SUCCESS(Status)) + { + /* Setup the device extension */ + DeviceExtension = DeviceObject->DeviceExtension; + DeviceExtension->Initialized = FALSE; - HeadlessDispatch( - HeadlessCmdQueryInformation, - NULL, - 0, - &HeadlessInformation, - &InfoSize - ); - if ((HeadlessInformation.Serial.TerminalType != HeadlessUndefinedPortType) && - ((HeadlessInformation.Serial.TerminalType != HeadlessSerialPort) || - (HeadlessInformation.Serial.TerminalAttached))) - { - RtlInitUnicodeString(&DriverName, L"\\Device\\SAC"); + /* Initialize the driver object */ + RtlFillMemoryUlong(DriverObject->MajorFunction, + RTL_NUMBER_OF(DriverObject->MajorFunction), + (ULONG_PTR)Dispatch); + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl; + DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DispatchShutdownControl; + DriverObject->FastIoDispatch = NULL; + DriverObject->DriverUnload = UnloadHandler; - Status = IoCreateDevice( - DriverObject, - sizeof(SAC_DEVICE_EXTENSION), - &DriverName, - FILE_DEVICE_UNKNOWN, - FILE_DEVICE_SECURE_OPEN, - FALSE, - &DeviceObject - ); - if (NT_SUCCESS(Status)) - { - DeviceExtension = DeviceObject->DeviceExtension; - DeviceExtension->Initialized = FALSE; + /* Initialize driver data */ + if (InitializeGlobalData(RegistryPath, DriverObject)) + { + /* Initialize device data */ + if (InitializeDeviceData(DeviceObject)) + { + /* We're all good, register a shutdown notification */ + IoRegisterShutdownNotification(DeviceObject); + return Status; + } + } - RtlFillMemoryUlong( - DriverObject->MajorFunction, - sizeof(DriverObject->MajorFunction) / sizeof(PVOID), - (ULONG_PTR)Dispatch); - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = - DispatchDeviceControl; - DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = - DispatchShutdownControl; - DriverObject->FastIoDispatch = NULL; - DriverObject->DriverUnload = UnloadHandler; + /* One of the initializations failed, bail out */ + Status = STATUS_INSUFFICIENT_RESOURCES; + } + else + { + /* Print a debug statement if enabled */ + SAC_DBG(SAC_DBG_INIT, "unable to create device object: %X\n", Status); + } - if (InitializeGlobalData(RegistryPath, DriverObject)) - { - if (InitializeDeviceData(DeviceObject)) - { - IoRegisterShutdownNotification(DeviceObject); - return Status; - } - } + /* Free any data we may have allocated and exit with failure */ + FreeGlobalData(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status 0x%x\n", Status); + return Status; + } - Status = STATUS_INSUFFICIENT_RESOURCES; - } - else - { - SAC_DBG(SAC_DBG_INIT, "unable to create device object: %X\n", Status); - } - - FreeGlobalData(); - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status 0x%x\n", Status); - return Status; - } - - return STATUS_PORT_DISCONNECTED; + /* EMS is not enabled */ + return STATUS_PORT_DISCONNECTED; } diff --git a/drivers/sac/driver/memory.c b/drivers/sac/driver/memory.c index fb77febccf6..6dfe2f1625e 100644 --- a/drivers/sac/driver/memory.c +++ b/drivers/sac/driver/memory.c @@ -1,108 +1,112 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/memory.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/memory.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ LONG TotalFrees, TotalBytesFreed, TotalAllocations, TotalBytesAllocated; KSPIN_LOCK MemoryLock; PSAC_MEMORY_LIST GlobalMemoryList; -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ BOOLEAN +NTAPI InitializeMemoryManagement(VOID) { - PSAC_MEMORY_ENTRY Entry; + PSAC_MEMORY_ENTRY Entry; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n"); - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n"); + /* Allocate a nonpaged heap for us to use */ + GlobalMemoryList = ExAllocatePoolWithTagPriority(NonPagedPool, + SAC_MEMORY_LIST_SIZE, + INITIAL_BLOCK_TAG, + HighPoolPriority); + if (GlobalMemoryList) + { + /* Initialize a lock for it */ + KeInitializeSpinLock(&MemoryLock); - GlobalMemoryList = ExAllocatePoolWithTagPriority( - NonPagedPool, - SAC_MEMORY_LIST_SIZE, - INITIAL_BLOCK_TAG, - HighPoolPriority); - if (GlobalMemoryList) - { - KeInitializeSpinLock(&MemoryLock); + /* Initialize the head of the list */ + GlobalMemoryList->Signature = GLOBAL_MEMORY_SIGNATURE; + GlobalMemoryList->LocalDescriptor = (PSAC_MEMORY_ENTRY)(GlobalMemoryList + 1); + GlobalMemoryList->Size = SAC_MEMORY_LIST_SIZE - sizeof(SAC_MEMORY_LIST); + GlobalMemoryList->Next = NULL; - GlobalMemoryList->Signature = GLOBAL_MEMORY_SIGNATURE; - GlobalMemoryList->LocalDescriptor = - (PSAC_MEMORY_ENTRY)(GlobalMemoryList + 1); - GlobalMemoryList->Size = SAC_MEMORY_LIST_SIZE - sizeof(SAC_MEMORY_LIST); + /* Initialize the first free entry */ + Entry = GlobalMemoryList->LocalDescriptor; + Entry->Signature = LOCAL_MEMORY_SIGNATURE; + Entry->Tag = FREE_POOL_TAG; + Entry->Size = GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY); - Entry = GlobalMemoryList->LocalDescriptor; - Entry->Signature = LOCAL_MEMORY_SIGNATURE; - Entry->Tag = FREE_POOL_TAG; - Entry->Size = GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY); + /* All done */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with TRUE.\n"); + return TRUE; + } - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with TRUE.\n"); - return TRUE; - } - - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with FALSE. No pool.\n"); - return FALSE; + /* No pool available to manage our heap */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with FALSE. No pool.\n"); + return FALSE; } VOID -FreeMemoryManagement( - VOID - ) +NTAPI +FreeMemoryManagement(VOID) { - PSAC_MEMORY_LIST Next; - KIRQL OldIrql; + PSAC_MEMORY_LIST Next; + KIRQL OldIrql; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n"); - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n"); + /* Acquire the memory lock while freeing the list(s) */ + KeAcquireSpinLock(&MemoryLock, &OldIrql); + while (GlobalMemoryList) + { + ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE); - KeAcquireSpinLock(&MemoryLock, &OldIrql); - while (GlobalMemoryList) - { - ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE); + /* While outisde of the lock, save the next list and free this one */ + KeReleaseSpinLock(&MemoryLock, OldIrql); + Next = GlobalMemoryList->Next; + ExFreePoolWithTag(GlobalMemoryList, 0); - KeReleaseSpinLock(&MemoryLock, OldIrql); + /* Reacquire the lock and see if there was another list to free */ + KeAcquireSpinLock(&MemoryLock, &OldIrql); + GlobalMemoryList = Next; + } - Next = GlobalMemoryList->Next; - - ExFreePoolWithTag(GlobalMemoryList, 0); - - KeAcquireSpinLock(&MemoryLock, &OldIrql); - GlobalMemoryList = Next; - } - - KeReleaseSpinLock(&MemoryLock, OldIrql); - SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting\n"); + /* All done */ + KeReleaseSpinLock(&MemoryLock, OldIrql); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting\n"); } PVOID -MyAllocatePool( - IN SIZE_T PoolSize, - IN ULONG Tag, - IN PCHAR File, - IN ULONG Line - ) +NTAPI +MyAllocatePool(IN SIZE_T PoolSize, + IN ULONG Tag, + IN PCHAR File, + IN ULONG Line) { - KIRQL OldIrql; - PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor; - PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor; - ULONG GlobalSize, ActualSize; - PVOID Buffer; + KIRQL OldIrql; + PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor; + PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor; + ULONG GlobalSize, ActualSize; + PVOID Buffer; + ASSERT("Tag != FREE_POOL_TAG"); + SAC_DBG(SAC_DBG_MM, "Entering.\n"); - ASSERT("Tag != FREE_POOL_TAG"); + /* Acquire the memory allocation lock and align the size request */ + KeAcquireSpinLock(&MemoryLock, &OldIrql);; + PoolSize = ALIGN_UP(PoolSize, ULONGLONG); - SAC_DBG(SAC_DBG_MM, "Entering.\n"); - - OldIrql = KfAcquireSpinLock(&MemoryLock); - PoolSize = ALIGN_UP(PoolSize, ULONGLONG); - - GlobalDescriptor = GlobalMemoryList; +#if _USE_SAC_HEAP_ALLOCATOR_ + GlobalDescriptor = GlobalMemoryList; KeAcquireSpinLock(&MemoryLock, &OldIrql); while (GlobalDescriptor) { @@ -189,43 +193,60 @@ MyAllocatePool( LocalDescriptor->Size = PoolSize; } } +#else + /* Shut the compiler up */ + NewDescriptor = GlobalDescriptor = NULL; + GlobalSize = (ULONG)NewDescriptor; + ActualSize = GlobalSize; + NextDescriptor = (PVOID)ActualSize; + NewDescriptor = (PVOID)NextDescriptor; - LocalDescriptor->Tag = Tag; - KeReleaseSpinLock(&MemoryLock, OldIrql); + /* Use the NT pool allocator */ + LocalDescriptor = ExAllocatePoolWithTag(NonPagedPool, + PoolSize + sizeof(*LocalDescriptor), + Tag); + LocalDescriptor->Size = PoolSize; +#endif + /* Set the tag, and release the lock */ + LocalDescriptor->Tag = Tag; + KeReleaseSpinLock(&MemoryLock, OldIrql); - InterlockedIncrement(&TotalAllocations); - InterlockedExchangeAdd(&TotalBytesAllocated, LocalDescriptor->Size); - SAC_DBG(1, "Returning block 0x%X.\n", LocalDescriptor); + /* Update our performance counters */ + InterlockedIncrement(&TotalAllocations); + InterlockedExchangeAdd(&TotalBytesAllocated, LocalDescriptor->Size); - Buffer = LocalDescriptor + 1; - RtlZeroMemory(Buffer, PoolSize); - return Buffer; + /* Return the buffer and zero it */ + SAC_DBG(SAC_DBG_MM, "Returning block 0x%X.\n", LocalDescriptor); + Buffer = LocalDescriptor + 1; + RtlZeroMemory(Buffer, PoolSize); + return Buffer; } VOID -MyFreePool( - IN PVOID *Block - ) +NTAPI +MyFreePool(IN PVOID *Block) { - PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor; - PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor; - ULONG GlobalSize, LocalSize; - PSAC_MEMORY_LIST GlobalDescriptor; - KIRQL OldIrql; + PSAC_MEMORY_ENTRY NextDescriptor; + PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor; + PSAC_MEMORY_ENTRY LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY)); + ULONG GlobalSize, LocalSize; + PSAC_MEMORY_LIST GlobalDescriptor; + KIRQL OldIrql; + SAC_DBG(SAC_DBG_MM, "Entering with block 0x%X.\n", LocalDescriptor); - LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY)); + /* Make sure this was a valid entry */ + ASSERT(LocalDescriptor->Size > 0); + ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE); - SAC_DBG(SAC_DBG_MM, "Entering with block 0x%X.\n", LocalDescriptor); + /* Update performance counters */ + InterlockedIncrement(&TotalFrees); + InterlockedExchangeAdd(&TotalBytesFreed, LocalDescriptor->Size); - ASSERT(LocalDescriptor->Size > 0); - ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE); + /* Acquire the memory alliocation lock */ + GlobalDescriptor = GlobalMemoryList; + KeAcquireSpinLock(&MemoryLock, &OldIrql); - InterlockedIncrement(&TotalFrees); - - InterlockedExchangeAdd(&TotalBytesFreed, LocalDescriptor->Size); - - GlobalDescriptor = GlobalMemoryList; - KeAcquireSpinLock(&MemoryLock, &OldIrql); +#if _USE_SAC_HEAP_ALLOCATOR_ while (GlobalDescriptor) { ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE); @@ -297,10 +318,22 @@ MyFreePool( FoundDescriptor->Size += (LocalDescriptor->Size + sizeof(SAC_MEMORY_ENTRY)); } +#else + /* Shut the compiler up */ + LocalSize = GlobalSize = 0; + ThisDescriptor = (PVOID)LocalSize; + NextDescriptor = (PVOID)GlobalSize; + GlobalDescriptor = (PVOID) ThisDescriptor; + FoundDescriptor = (PVOID)GlobalDescriptor; + GlobalDescriptor = (PVOID) NextDescriptor; + NextDescriptor = (PVOID) FoundDescriptor; - KeReleaseSpinLock(&MemoryLock, OldIrql); - *Block = NULL; + /* Use the NT pool allocator*/ + ExFreePool(LocalDescriptor); +#endif - SAC_DBG(SAC_DBG_MM, "exiting.\n"); - return; + /* Release the lock, delete the address, and return */ + KeReleaseSpinLock(&MemoryLock, OldIrql); + *Block = NULL; + SAC_DBG(SAC_DBG_MM, "exiting.\n"); } diff --git a/drivers/sac/driver/rawchan.c b/drivers/sac/driver/rawchan.c index 6a38bd0a97c..098d78dd97a 100644 --- a/drivers/sac/driver/rawchan.c +++ b/drivers/sac/driver/rawchan.c @@ -1,143 +1,373 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/rawchan.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/rawchan.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +/* FUNCTIONS *****************************************************************/ + +#define SAC_RAW_OBUFFER_SIZE 0x2000 +#define SAC_RAW_IBUFFER_SIZE 0x2000 NTSTATUS -RawChannelCreate( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelCreate(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER(Channel); + + Channel->OBuffer = SacAllocatePool(SAC_RAW_OBUFFER_SIZE, GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(Channel->OBuffer); + + Channel->IBuffer = SacAllocatePool(SAC_RAW_IBUFFER_SIZE, GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(Channel->IBuffer); + + Channel->OBufferIndex = 0; + Channel->OBufferFirstGoodIndex = 0; + Channel->ChannelHasNewIBufferData = FALSE; + Channel->ChannelHasNewOBufferData = FALSE; + + return STATUS_SUCCESS; } NTSTATUS -RawChannelDestroy( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelDestroy(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER(Channel); + + if (Channel->OBuffer) + { + SacFreePool(Channel->OBuffer); + } + + if (Channel->IBuffer) + { + SacFreePool(Channel->IBuffer); + } + + return ChannelDestroy(Channel); +} + +FORCEINLINE +BOOLEAN +ChannelHasNewOBufferData(IN PSAC_CHANNEL Channel) +{ + return Channel->ChannelHasNewOBufferData; +} + +FORCEINLINE +BOOLEAN +ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel) +{ + return Channel->ChannelHasNewIBufferData; } NTSTATUS -RawChannelORead( - IN PSAC_CHANNEL Channel, - IN PCHAR Buffer, - IN ULONG BufferSize, - OUT PULONG ByteCount - ) +NTAPI +RawChannelORead(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + OUT PULONG ByteCount) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + ULONG NextIndex; + + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Buffer); + CHECK_PARAMETER3(BufferSize > 0); + CHECK_PARAMETER4(ByteCount); + + *ByteCount = 0; + + if (ChannelHasNewOBufferData(Channel)) + { + Status = STATUS_SUCCESS; + + while (TRUE) + { + Buffer[(*ByteCount)++] = Channel->OBuffer[Channel->OBufferFirstGoodIndex]; + + NextIndex = (Channel->OBufferFirstGoodIndex + 1) & (SAC_OBUFFER_SIZE - 1); + Channel->OBufferFirstGoodIndex = NextIndex; + + if (NextIndex == Channel->OBufferIndex) + { + _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0); + break; + } + + ASSERT(*ByteCount > 0); + + if (*ByteCount >= BufferSize) break; + } + } + else + { + Status = STATUS_NO_DATA_DETECTED; + } + + if (Channel->OBufferFirstGoodIndex == Channel->OBufferIndex) + { + ASSERT(ChannelHasNewOBufferData(Channel) == FALSE); + } + + if (ChannelHasNewOBufferData(Channel) == FALSE) + { + ASSERT(Channel->OBufferFirstGoodIndex == Channel->OBufferIndex); + } + + return Status; } NTSTATUS -RawChannelOEcho( - IN PSAC_CHANNEL Channel, - IN PWCHAR String, - IN ULONG Length - ) +NTAPI +RawChannelOEcho(IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status = STATUS_SUCCESS; + + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(String); + + if (Length) + { + Status = ConMgrWriteData(Channel, String, Length); + if (NT_SUCCESS(Status)) ConMgrFlushData(Channel); + } + + return Status; } NTSTATUS -RawChannelOWrite2( - IN PSAC_CHANNEL Channel, - IN PCHAR String, - IN ULONG Size - ) +NTAPI +RawChannelOWrite2(IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Size) { - return STATUS_NOT_IMPLEMENTED; + BOOLEAN Overflow; + ULONG i, NextIndex; + + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(String); + + Overflow = FALSE; + + for (i = 0; i < Size; i++) + { + if ((Channel->OBufferIndex == Channel->OBufferFirstGoodIndex) && + ((i) || (ChannelHasNewOBufferData(Channel)))) + { + Overflow = TRUE; + } + + ASSERT(Channel->OBufferIndex < SAC_RAW_OBUFFER_SIZE); + + Channel->OBuffer[Channel->OBufferIndex] = String[i]; + + NextIndex = (Channel->OBufferIndex + 1) & (SAC_RAW_OBUFFER_SIZE - 1); + Channel->OBufferIndex = NextIndex; + + if (Overflow) Channel->OBufferFirstGoodIndex = NextIndex; + } + + _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 1); + + return STATUS_SUCCESS; } NTSTATUS -RawChannelOFlush( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelOFlush(IN PSAC_CHANNEL Channel) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + ULONG ByteCount; + CHAR Dummy; + CHECK_PARAMETER1(Channel); + + while (ChannelHasNewOBufferData(Channel)) + { + Status = RawChannelORead(Channel, &Dummy, sizeof(Dummy), &ByteCount); + if (!NT_SUCCESS(Status)) return Status; + + CHECK_PARAMETER_WITH_STATUS(ByteCount == 1, STATUS_UNSUCCESSFUL); + + Status = ConMgrWriteData(Channel, &Dummy, sizeof(Dummy)); + if (!NT_SUCCESS(Status)) return Status; + } + + return ConMgrFlushData(Channel); } ULONG -RawChannelGetIBufferIndex( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelGetIBufferIndex(IN PSAC_CHANNEL Channel) { - return 0; + ASSERT(Channel); + ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE); + + return Channel->IBufferIndex; } VOID -RawChannelSetIBufferIndex( - IN PSAC_CHANNEL Channel, - IN ULONG BufferIndex - ) +NTAPI +RawChannelSetIBufferIndex(IN PSAC_CHANNEL Channel, + IN ULONG BufferIndex) { + NTSTATUS Status; + ASSERT(Channel); + ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE); + Channel->IBufferIndex = BufferIndex; + Channel->ChannelHasNewIBufferData = BufferIndex != 0; + + if (!Channel->IBufferIndex) + { + if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) + { + ChannelClearEvent(Channel, HasNewDataEvent); + UNREFERENCED_PARAMETER(Status); + } + } } NTSTATUS -RawChannelOWrite( - IN PSAC_CHANNEL Channel, - IN PWCHAR String, - IN ULONG Length - ) +NTAPI +RawChannelOWrite(IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(String); + + if ((ConMgrIsWriteEnabled(Channel)) && (Channel->WriteEnabled)) + { + return RawChannelOEcho(Channel, String, Length); + } + + return RawChannelOWrite2(Channel, String, Length); } NTSTATUS -RawChannelIRead( - IN PSAC_CHANNEL Channel, - IN PCHAR Buffer, - IN ULONG BufferSize, - IN PULONG ReturnBufferSize - ) +NTAPI +RawChannelIRead(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + IN PULONG ReturnBufferSize) { - return STATUS_NOT_IMPLEMENTED; + ULONG CopyChars; + + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Buffer); + CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE); + + *ReturnBufferSize = 0; + + if (Channel->ChannelInputBufferLength(Channel) == 0) + { + ASSERT(ChannelHasNewIBufferData(Channel) == FALSE); + } + else + { + CopyChars = Channel->ChannelInputBufferLength(Channel); + if (CopyChars > BufferSize) CopyChars = BufferSize; + ASSERT(CopyChars <= Channel->ChannelInputBufferLength(Channel)); + + RtlCopyMemory(Buffer, Channel->IBuffer, CopyChars); + + RawChannelSetIBufferIndex(Channel, + RawChannelGetIBufferIndex(Channel) - CopyChars); + + if (Channel->ChannelInputBufferLength(Channel)) + { + RtlMoveMemory(Channel->IBuffer, + &Channel->IBuffer[CopyChars], + Channel->ChannelInputBufferLength(Channel)); + } + + *ReturnBufferSize = CopyChars; + } + + return STATUS_SUCCESS; } NTSTATUS -RawChannelIBufferIsFull( - IN PSAC_CHANNEL Channel, - PBOOLEAN BufferStatus - ) +NTAPI +RawChannelIBufferIsFull(IN PSAC_CHANNEL Channel, + OUT PBOOLEAN BufferStatus) { - return STATUS_NOT_IMPLEMENTED; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(BufferStatus); + + *BufferStatus = RawChannelGetIBufferIndex(Channel) > SAC_RAW_IBUFFER_SIZE; + return STATUS_SUCCESS; } ULONG -RawChannelIBufferLength( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelIBufferLength(IN PSAC_CHANNEL Channel) { - return 0; + ASSERT(Channel); + return RawChannelGetIBufferIndex(Channel); } CHAR -RawChannelIReadLast( - IN PSAC_CHANNEL Channel - ) +NTAPI +RawChannelIReadLast(IN PSAC_CHANNEL Channel) { - return 0; + UCHAR LastChar = 0; + + ASSERT(Channel); + + if (Channel->ChannelInputBufferLength(Channel)) + { + RawChannelSetIBufferIndex(Channel, RawChannelGetIBufferIndex(Channel) - 1); + + LastChar = Channel->IBuffer[RawChannelGetIBufferIndex(Channel)]; + Channel->IBuffer[RawChannelGetIBufferIndex(Channel)] = 0; + } + + return LastChar; } NTSTATUS -RawChannelIWrite( - IN PSAC_CHANNEL Channel, - IN PCHAR Buffer, - IN ULONG BufferSize - ) +NTAPI +RawChannelIWrite(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + BOOLEAN IsFull; + ULONG Index; + + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Buffer); + CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE); + + Status = RawChannelIBufferIsFull(Channel, &IsFull); + if (!NT_SUCCESS(Status)) return Status; + + if (IsFull) return STATUS_UNSUCCESSFUL; + + Index = RawChannelGetIBufferIndex(Channel); + if ((SAC_RAW_IBUFFER_SIZE - Index) >= BufferSize) return STATUS_INSUFFICIENT_RESOURCES; + + RtlCopyMemory(&Channel->IBuffer[Index], Buffer, BufferSize); + + RawChannelSetIBufferIndex(Channel, BufferSize + Index); + + if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) + { + ChannelSetEvent(Channel, HasNewDataEvent); + } + + return STATUS_SUCCESS; } diff --git a/drivers/sac/driver/sacdrv.h b/drivers/sac/driver/sacdrv.h index 0936712eb61..fef618c989a 100644 --- a/drivers/sac/driver/sacdrv.h +++ b/drivers/sac/driver/sacdrv.h @@ -1,390 +1,1016 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/sacdrv.h - * PURPOSE: Header for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/sacdrv.h + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ + #include -#include +#include +#include +#include +#include +#include +#include <../../../ntoskrnl/include/internal/hdl.h> +#include +#include -#define SAC_DBG_ENTRY_EXIT 0x01 -#define SAC_DBG_INIT 0x04 -#define SAC_DBG_MM 0x1000 +/* DEFINES *******************************************************************/ -#define SAC_DBG(x, ...) \ - if (SACDebug & x) \ - { \ - DbgPrint("SAC %s: ", __FUNCTION__); \ - DbgPrint(__VA_ARGS__); \ - } +// +// SAC Heap Allocator Macros +// +#define SacAllocatePool(Length, Tag) \ + MyAllocatePool(Length, Tag, __FILE__, __LINE__) +#define SacFreePool(Pointer) \ + MyFreePool((PVOID*)(&Pointer)) -#define CHECK_PARAMETER_WITH_STATUS(Parameter, Status) \ -{ \ - ASSERT((Parameter)); \ - if (!Parameter) \ - { \ - return Status; \ - } \ +// +// SAC Debugging Macro and Constants +// +#define SAC_DBG_ENTRY_EXIT 0x01 +#define SAC_DBG_UTIL 0x02 +#define SAC_DBG_INIT 0x04 +#define SAC_DBG_MM 0x1000 +#define SAC_DBG(x, ...) \ + if (SACDebug & x) \ + { \ + DbgPrint("SAC %s: ", __FUNCTION__); \ + DbgPrint(__VA_ARGS__); \ + } + +// +// SAC Parameter Checking Macros +// +#define CHECK_PARAMETER_WITH_STATUS(Parameter, Status) \ +{ \ + ASSERT(((PVOID)(Parameter)) != NULL); \ + if (((PVOID)(Parameter)) == NULL) \ + { \ + return Status; \ + } \ } -#define CHECK_PARAMETER(x) \ - CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER) -#define CHECK_PARAMETER1(x) \ - CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_1) -#define CHECK_PARAMETER2(x) \ - CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_2) -#define CHECK_PARAMETER3(x) \ - CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_3) -#define CHECK_ALLOCATION(x) \ - CHECK_PARAMETER_WITH_STATUS(x, STATUS_OUT_OF_MEMORY) - -#define SacAllocatePool(Length, Tag) \ - MyAllocatePool(Length, Tag, __FILE__, __LINE__) +#define CHECK_PARAMETER(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER) +#define CHECK_PARAMETER1(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_1) +#define CHECK_PARAMETER2(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_2) +#define CHECK_PARAMETER3(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_3) +#define CHECK_PARAMETER4(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_INVALID_PARAMETER_4) +#define CHECK_ALLOCATION(x) \ + CHECK_PARAMETER_WITH_STATUS(x, STATUS_NO_MEMORY) -#define ChannelLock(Channel, x) \ -{ \ - KeWaitForSingleObject( \ - &(Channel)->x.Lock, \ - Executive, \ - KernelMode, \ - FALSE, \ - NULL); \ - ASSERT((Channel)->x.RefCount == 0); \ - InterlockedIncrement(&(Channel)->x.RefCount); \ +// +// SAC Channel Event Macros +// +#define ChannelInitializeEvent(Channel, Attributes, x) \ +{ \ + PVOID Object, WaitObject; \ + if (Attributes->x) \ + { \ + if (!VerifyEventWaitable(Attributes->x, &Object, &WaitObject)) \ + { \ + goto FailChannel; \ + } \ + Channel->x = Attributes->x; \ + Channel->x##ObjectBody = Object; \ + Channel->x##WaitObjectBody = WaitObject; \ + } \ +} +#define ChannelUninitializeEvent(Channel, x, f) \ +{ \ + ASSERT(ChannelGetFlags(Channel) & (f)); \ + ASSERT(Channel->x##ObjectBody); \ + ASSERT(Channel->x##WaitObjectBody); \ + if (Channel->x##ObjectBody) \ + { \ + ObDereferenceObject(Channel->x##ObjectBody); \ + Channel->Flags &= ~(f); \ + Channel->x = NULL; \ + Channel->x##ObjectBody = NULL; \ + Channel->x##WaitObjectBody = NULL; \ + } \ +} +#define ChannelSetEvent(Channel, x) \ +{ \ + ASSERT(Channel->x); \ + ASSERT(Channel->x##ObjectBody); \ + ASSERT(Channel->x##WaitObjectBody); \ + if (Channel->x##WaitObjectBody) \ + { \ + KeSetEvent(Channel->x##WaitObjectBody, EVENT_INCREMENT, FALSE); \ + Status = STATUS_SUCCESS; \ + } \ + else \ + { \ + Status = STATUS_UNSUCCESSFUL; \ + } \ +} +#define ChannelClearEvent(Channel, x) \ +{ \ + ASSERT(Channel->x); \ + ASSERT(Channel->x##ObjectBody); \ + ASSERT(Channel->x##WaitObjectBody); \ + if (Channel->x##WaitObjectBody) \ + { \ + KeClearEvent(Channel->x##WaitObjectBody); \ + Status = STATUS_SUCCESS; \ + } \ + else \ + { \ + Status = STATUS_UNSUCCESSFUL; \ + } \ } -#define ChannelUnlock(Channel, x) \ -{ \ - ASSERT((Channel)->x.RefCount == 1); \ - InterlockedDecrement(&(Channel)->x.RefCount); \ - KeReleaseSemaphore( \ - &(Channel)->x.Lock, \ - SEMAPHORE_INCREMENT, \ - 1, \ - FALSE); \ -} +// +// SAC Pool Tags, taken from pooltag.txt: +// +// Rcp? - sacdrv.sys - SAC Driver (Headless) +// RcpA - sacdrv.sys - Internal memory mgr alloc block +// RcpI - sacdrv.sys - Internal memory mgr initial heap block +// RcpS - sacdrv.sys - Security related block +#define GENERIC_TAG '?pcR' +#define ALLOC_BLOCK_TAG 'ApcR' +#define INITIAL_BLOCK_TAG 'IpcR' +#define SECURITY_BLOCK_TAG 'SpcR' +#define FREE_POOL_TAG 'FpcR' +#define GLOBAL_BLOCK_TAG 'GpcR' +#define CHANNEL_BLOCK_TAG 'CpcR' +#define LOCAL_MEMORY_SIGNATURE 'SSEL' +#define GLOBAL_MEMORY_SIGNATURE 'DAEH' -#define ChannelLockOBuffer(Channel) ChannelLock(Channel, ChannelOBufferLock); -#define ChannelUnlockOBuffer(Channel) ChannelUnlock(Channel, ChannelOBufferLock); -#define ChannelLockIBuffer(Channel) ChannelLock(Channel, ChannelIBufferLock); -#define ChannelUnlockIBuffer(Channel) ChannelUnlock(Channel, ChannelIBufferLock); -#define ChannelLockAttributes(Channel) ChannelLock(Channel, ChannelAttributesLock); -#define ChannelUnlockAttributes(Channel) ChannelUnlock(Channel, ChannelAttributesLock); +// +// Size Definitions +// +#define SAC_MEMORY_LIST_SIZE (1 * 1024 * 1024) // 1MB +#define SAC_OBUFFER_SIZE (2 * 1024) // 2KB +#define SAC_CHANNEL_NAME_SIZE 64 +#define SAC_CHANNEL_DESCRIPTION_SIZE 256 +#define SAC_MAX_CHANNELS 10 +#define SAC_SERIAL_PORT_BUFFER_SIZE 1024 // 1KB +#define SAC_MAX_MESSAGES 200 -#define ChannelInitializeEvent(Channel, Attributes, x) \ -{ \ - PVOID Object, WaitObject; \ - if (Attributes->x) \ - { \ - if (!VerifyEventWaitable(Attributes->x, &Object, &WaitObject)) \ - { \ - goto FailChannel; \ - } \ - Channel->x = Attributes->x; \ - Channel->x##ObjectBody = Object; \ - Channel->x##WaitObjectBody = WaitObject; \ - } \ -} - -#define ChannelSetEvent(Channel, x) \ -{ \ - ASSERT(Channel->x); \ - ASSERT(Channel->x##ObjectBody); \ - ASSERT(Channel->x##WaitObjectBody); \ - if (Channel->x) \ - { \ - KeSetEvent(Channel->x, EVENT_INCREMENT, FALSE); \ - Status = STATUS_SUCCESS; \ - } \ - else \ - { \ - Status = STATUS_UNSUCCESSFUL; \ - } \ -} - -#define ChannelClearEvent(Channel, x) \ -{ \ - ASSERT(Channel->x); \ - ASSERT(Channel->x##ObjectBody); \ - ASSERT(Channel->x##WaitObjectBody); \ - if (Channel->x) \ - { \ - KeClearEvent(Channel->x); \ - Status = STATUS_SUCCESS; \ - } \ - else \ - { \ - Status = STATUS_UNSUCCESSFUL; \ - } \ -} - -//Rcp? - sacdrv.sys - SAC Driver (Headless) -//RcpA - sacdrv.sys - Internal memory mgr alloc block -//RcpI - sacdrv.sys - Internal memory mgr initial heap block -//RcpS - sacdrv.sys - Security related block -#define GENERIC_TAG '?pcR' -#define ALLOC_BLOCK_TAG 'ApcR' -#define INITIAL_BLOCK_TAG 'IpcR' -#define SECURITY_BLOCK_TAG 'SpcR' -#define FREE_POOL_TAG 'FpcR' - -#define LOCAL_MEMORY_SIGNATURE 'SSEL' -#define GLOBAL_MEMORY_SIGNATURE 'DAEH' - -#define SAC_MEMORY_LIST_SIZE (1 * 1024 * 1024) - -#define SAC_OBUFFER_SIZE (2 * 1024) - -#define SAC_CHANNEL_FLAG_CLOSE_EVENT 0x2 -#define SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT 0x4 -#define SAC_CHANNEL_FLAG_LOCK_EVENT 0x8 -#define SAC_CHANNEL_FLAG_REDRAW_EVENT 0x10 - -typedef struct _SAC_MEMORY_ENTRY -{ - ULONG Signature; - ULONG Tag; - ULONG Size; -} SAC_MEMORY_ENTRY, *PSAC_MEMORY_ENTRY; - -typedef struct _SAC_MEMORY_LIST -{ - ULONG Signature; - PSAC_MEMORY_ENTRY LocalDescriptor; - ULONG Size; - struct _SAC_MEMORY_LIST* Next; -} SAC_MEMORY_LIST, *PSAC_MEMORY_LIST; - -typedef enum _SAC_CHANNEL_TYPE -{ - VtUtf8, - Cmd, - Raw -} SAC_CHANNEL_TYPE; - -typedef enum _SAC_CHANNEL_STATUS -{ - Inactive, - Active -} SAC_CHANNEL_STATUS, *PSAC_CHANNEL_STATUS; - -typedef struct _SAC_CHANNEL_ID -{ - GUID ChannelGuid; - ULONG ChannelId; -} SAC_CHANNEL_ID, *PSAC_CHANNEL_ID; - -typedef struct _SAC_CHANNEL_LOCK -{ - LONG RefCount; - KSEMAPHORE Lock; -} SAC_CHANNEL_LOCK, *PSAC_CHANNEL_LOCK; +// +// Channel flags +// +#define SAC_CHANNEL_FLAG_INTERNAL 0x1 +#define SAC_CHANNEL_FLAG_CLOSE_EVENT 0x2 +#define SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT 0x4 +#define SAC_CHANNEL_FLAG_LOCK_EVENT 0x8 +#define SAC_CHANNEL_FLAG_REDRAW_EVENT 0x10 +#define SAC_CHANNEL_FLAG_APPLICATION 0x20 +// +// Forward definitions +// struct _SAC_CHANNEL; +// +// Structures used by the SAC Heap Allocator +// +typedef struct _SAC_MEMORY_ENTRY +{ + ULONG Signature; + ULONG Tag; + ULONG Size; +} SAC_MEMORY_ENTRY, *PSAC_MEMORY_ENTRY; +typedef struct _SAC_MEMORY_LIST +{ + ULONG Signature; + PSAC_MEMORY_ENTRY LocalDescriptor; + ULONG Size; + struct _SAC_MEMORY_LIST* Next; +} SAC_MEMORY_LIST, *PSAC_MEMORY_LIST; + +typedef struct _SAC_MESSAGE_ENTRY +{ + ULONG Index; + PWCHAR Buffer; +} SAC_MESSAGE_ENTRY, *PSAC_MESSAGE_ENTRY; + +// +// SAC supports 3 different channel output types +// +typedef enum _SAC_CHANNEL_TYPE +{ + VtUtf8, + Cmd, + Raw +} SAC_CHANNEL_TYPE; + +// +// A SAC channel can be active or inactive +// +typedef enum _SAC_CHANNEL_STATUS +{ + Inactive, + Active +} SAC_CHANNEL_STATUS, *PSAC_CHANNEL_STATUS; + +// +// A SAC channel identifier +// +typedef struct _SAC_CHANNEL_ID +{ + GUID ChannelGuid; + ULONG ChannelId; +} SAC_CHANNEL_ID, *PSAC_CHANNEL_ID; + +// +// Reference-counted SAC channel semaphore lock +// +typedef struct _SAC_CHANNEL_LOCK +{ + LONG RefCount; + KSEMAPHORE Lock; +} SAC_CHANNEL_LOCK, *PSAC_CHANNEL_LOCK; + +// +// Channel callbacks +// typedef NTSTATUS -(*PSAC_CHANNEL_CREATE)( - IN struct _SAC_CHANNEL* Channel - ); +(NTAPI *PSAC_CHANNEL_CREATE)( + IN struct _SAC_CHANNEL* Channel +); typedef NTSTATUS -(*PSAC_CHANNEL_DESTROY)( - IN struct _SAC_CHANNEL* Channel - ); +(NTAPI *PSAC_CHANNEL_DESTROY)( + IN struct _SAC_CHANNEL* Channel +); typedef NTSTATUS -(*PSAC_CHANNEL_OREAD)( - IN struct _SAC_CHANNEL* Channel, - IN PCHAR Buffer, - IN ULONG BufferSize, - OUT PULONG ByteCount - ); +(NTAPI *PSAC_CHANNEL_OREAD)( + IN struct _SAC_CHANNEL* Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + OUT PULONG ByteCount +); typedef NTSTATUS -(*PSAC_CHANNEL_OECHO)( - IN struct _SAC_CHANNEL* Channel, - IN PWCHAR String, - IN ULONG Length - ); +(NTAPI *PSAC_CHANNEL_OECHO)( + IN struct _SAC_CHANNEL* Channel, + IN PCHAR String, + IN ULONG Length +); typedef NTSTATUS -(*PSAC_CHANNEL_OFLUSH)( - IN struct _SAC_CHANNEL* Channel - ); +(NTAPI *PSAC_CHANNEL_OFLUSH)( + IN struct _SAC_CHANNEL* Channel +); typedef NTSTATUS -(*PSAC_CHANNEL_OWRITE)( - IN struct _SAC_CHANNEL* Channel, - IN PWCHAR String, - IN ULONG Length - ); +(NTAPI *PSAC_CHANNEL_OWRITE)( + IN struct _SAC_CHANNEL* Channel, + IN PCHAR String, + IN ULONG Length +); typedef NTSTATUS -(*PSAC_CHANNEL_IREAD)( - IN struct _SAC_CHANNEL* Channel, - IN PWCHAR Buffer, - IN ULONG BufferSize, - IN PULONG ReturnBufferSize - ); +(NTAPI *PSAC_CHANNEL_IREAD)( + IN struct _SAC_CHANNEL* Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + IN PULONG ReturnBufferSize +); typedef NTSTATUS -(*PSAC_CHANNEL_IBUFFER_FULL)( - IN struct _SAC_CHANNEL* Channel, - OUT PBOOLEAN BufferStatus - ); +(NTAPI *PSAC_CHANNEL_IBUFFER_FULL)( + IN struct _SAC_CHANNEL* Channel, + OUT PBOOLEAN BufferStatus +); typedef -NTSTATUS -(*PSAC_CHANNEL_IBUFFER_LENGTH)( - IN struct _SAC_CHANNEL* Channel - ); +ULONG +(NTAPI *PSAC_CHANNEL_IBUFFER_LENGTH)( + IN struct _SAC_CHANNEL* Channel +); typedef CHAR -(*PSAC_CHANNEL_IREAD_LAST)( - IN struct _SAC_CHANNEL* Channel - ); +(NTAPI *PSAC_CHANNEL_IREAD_LAST)( + IN struct _SAC_CHANNEL* Channel +); typedef NTSTATUS -(*PSAC_CHANNEL_IWRITE)( - IN struct _SAC_CHANNEL* Channel, - IN PCHAR Buffer, - IN ULONG BufferSize - ); +(NTAPI *PSAC_CHANNEL_IWRITE)( + IN struct _SAC_CHANNEL* Channel, + IN PCHAR Buffer, + IN ULONG BufferSize +); +// +// A channel and its attributes +// typedef struct _SAC_CHANNEL { - ULONG Index; - SAC_CHANNEL_ID ChannelId; - HANDLE CloseEvent; - PVOID CloseEventObjectBody; - PKEVENT CloseEventWaitObjectBody; - HANDLE HasNewDataEvent; - PVOID HasNewDataEventObjectBody; - PKEVENT HasNewDataEventWaitObjectBody; - HANDLE LockEvent; - PVOID LockEventObjectBody; - PKEVENT LockEventWaitObjectBody; - HANDLE RedrawEvent; - PVOID RedrawEventObjectBody; - PKEVENT RedrawEventWaitObjectBody; - PFILE_OBJECT FileObject; - SAC_CHANNEL_TYPE ChannelType; - SAC_CHANNEL_STATUS ChannelStatus; - WCHAR NameBuffer[64 + 1]; - WCHAR DescriptionBuffer[256 + 1]; - ULONG Flags; - GUID ApplicationType; - BOOLEAN WriteEnabled; - ULONG IBufferIndex; - PVOID IBuffer; - BOOLEAN ChannelHasNewIBufferData; - UCHAR CursorRow; - UCHAR CursorCol; - UCHAR CursorY; - UCHAR CursorX; - UCHAR CursorVisible; - PVOID OBuffer; - ULONG OBufferIndex; - ULONG OBufferFirstGoodIndex; - BOOLEAN ChannelHasNewOBufferData; - PSAC_CHANNEL_CREATE ChannelCreate; - PSAC_CHANNEL_DESTROY ChannelDestroy; - PSAC_CHANNEL_OFLUSH OBufferFlush; - PSAC_CHANNEL_OECHO OBufferEcho; - PSAC_CHANNEL_OWRITE OBufferWrite; - PSAC_CHANNEL_OREAD OBufferRead; - PSAC_CHANNEL_OWRITE IBufferWrite; - PSAC_CHANNEL_IREAD IBufferRead; - PSAC_CHANNEL_IREAD_LAST IBufferReadLast; - PSAC_CHANNEL_IBUFFER_FULL IBufferIsFull; - PSAC_CHANNEL_IBUFFER_LENGTH IBufferLength; - SAC_CHANNEL_LOCK ChannelAttributeLock; - SAC_CHANNEL_LOCK ChannelOBufferLock; - SAC_CHANNEL_LOCK ChannelIBufferLock; + LONG Index; + SAC_CHANNEL_ID ChannelId; + HANDLE CloseEvent; + PVOID CloseEventObjectBody; + PKEVENT CloseEventWaitObjectBody; + HANDLE HasNewDataEvent; + PVOID HasNewDataEventObjectBody; + PKEVENT HasNewDataEventWaitObjectBody; + HANDLE LockEvent; + PVOID LockEventObjectBody; + PKEVENT LockEventWaitObjectBody; + HANDLE RedrawEvent; + PVOID RedrawEventObjectBody; + PKEVENT RedrawEventWaitObjectBody; + PFILE_OBJECT FileObject; + SAC_CHANNEL_TYPE ChannelType; + SAC_CHANNEL_STATUS ChannelStatus; + WCHAR NameBuffer[SAC_CHANNEL_NAME_SIZE + 1]; + WCHAR DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE + 1]; + ULONG Flags; + GUID ApplicationType; + LONG WriteEnabled; + ULONG IBufferIndex; + PCHAR IBuffer; + LONG ChannelHasNewIBufferData; + UCHAR CursorRow; + UCHAR CursorCol; + UCHAR CursorY; + UCHAR CursorX; + UCHAR CursorVisible; + PCHAR OBuffer; + ULONG OBufferIndex; + ULONG OBufferFirstGoodIndex; + LONG ChannelHasNewOBufferData; + PSAC_CHANNEL_CREATE ChannelCreate; + PSAC_CHANNEL_DESTROY ChannelDestroy; + PSAC_CHANNEL_OFLUSH ChannelOutputFlush; + PSAC_CHANNEL_OECHO ChannelOutputEcho; + PSAC_CHANNEL_OWRITE ChannelOutputWrite; + PSAC_CHANNEL_OREAD ChannelOutputRead; + PSAC_CHANNEL_IWRITE ChannelInputWrite; + PSAC_CHANNEL_IREAD ChannelInputRead; + PSAC_CHANNEL_IREAD_LAST ChannelInputReadLast; + PSAC_CHANNEL_IBUFFER_FULL ChannelInputBufferIsFull; + PSAC_CHANNEL_IBUFFER_LENGTH ChannelInputBufferLength; + SAC_CHANNEL_LOCK ChannelAttributeLock; + SAC_CHANNEL_LOCK ChannelOBufferLock; + SAC_CHANNEL_LOCK ChannelIBufferLock; } SAC_CHANNEL, *PSAC_CHANNEL; -typedef struct _SAC_DEVICE_EXTENSION -{ - PDEVICE_OBJECT DeviceObject; - BOOLEAN Initialized; - BOOLEAN Rundown; - BOOLEAN PriorityFail; - KPRIORITY PriorityBoost; - PEPROCESS Process; - KSPIN_LOCK Lock; - KEVENT RundownEvent; - KEVENT Event; - HANDLE WorkerThreadHandle; - KEVENT WorkerThreadEvent; - KTIMER Timer; - KDPC Dpc; - LIST_ENTRY List; -} SAC_DEVICE_EXTENSION, *PSAC_DEVICE_EXTENSION; - typedef struct _SAC_CHANNEL_ATTRIBUTES { - SAC_CHANNEL_TYPE ChannelType; - WCHAR NameBuffer[64 + 1]; - WCHAR DescriptionBuffer[256 + 1]; - ULONG Flag; - PKEVENT CloseEvent; - PKEVENT HasNewDataEvent; - PKEVENT LockEvent; - PKEVENT RedrawEvent; - GUID ChannelId; + SAC_CHANNEL_TYPE ChannelType; + WCHAR NameBuffer[64 + 1]; + WCHAR DescriptionBuffer[256 + 1]; + ULONG Flag; + HANDLE CloseEvent; + HANDLE HasNewDataEvent; + HANDLE LockEvent; + HANDLE RedrawEvent; + GUID ChannelId; } SAC_CHANNEL_ATTRIBUTES, *PSAC_CHANNEL_ATTRIBUTES; +// +// Cached Machine Information +// +typedef struct _SAC_MACHINE_INFO +{ + PWCHAR MachineName; + PWCHAR MachineGuid; + PWCHAR ProcessorArchitecture; + PWCHAR MajorVersion; + PWCHAR BuildNumber; + PWCHAR ProductType; + PWCHAR ServicePack; +} SAC_MACHINE_INFO, *PSAC_MACHINE_INFO; + +// +// The device extension for the SAC +// +typedef struct _SAC_DEVICE_EXTENSION +{ + PDEVICE_OBJECT DeviceObject; + BOOLEAN Initialized; + BOOLEAN Rundown; + BOOLEAN PriorityFail; + BOOLEAN RundownInProgress; + KPRIORITY PriorityBoost; + PEPROCESS Process; + KSPIN_LOCK Lock; + KEVENT RundownEvent; + KEVENT Event; + HANDLE WorkerThreadHandle; + KEVENT WorkerThreadEvent; + KTIMER Timer; + KDPC Dpc; + LIST_ENTRY List; +} SAC_DEVICE_EXTENSION, *PSAC_DEVICE_EXTENSION; + +// +// Dispatch Routines +// NTSTATUS +NTAPI Dispatch( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ); NTSTATUS NTAPI DispatchDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ); NTSTATUS +NTAPI DispatchShutdownControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp ); VOID +NTAPI UnloadHandler( - IN PDRIVER_OBJECT DriverObject + IN PDRIVER_OBJECT DriverObject +); + +// +// Initialization and shutdown routines +// +VOID +NTAPI +FreeGlobalData( + VOID ); VOID -FreeGlobalData( - VOID +NTAPI +FreeDeviceData( + IN PDEVICE_OBJECT DeviceObject ); BOOLEAN +NTAPI InitializeDeviceData( - IN PDEVICE_OBJECT DeviceObject + IN PDEVICE_OBJECT DeviceObject ); BOOLEAN +NTAPI InitializeGlobalData( - IN PUNICODE_STRING RegistryPath, - IN PDRIVER_OBJECT DriverObject + IN PUNICODE_STRING RegistryPath, + IN PDRIVER_OBJECT DriverObject ); -extern ULONG SACDebug; +BOOLEAN +NTAPI +InitializeMemoryManagement( + VOID +); +VOID +NTAPI +FreeMemoryManagement( + VOID +); + +VOID +NTAPI +InitializeCmdEventInfo( + VOID +); + +VOID +NTAPI +InitializeMachineInformation( + VOID +); + +NTSTATUS +NTAPI +PreloadGlobalMessageTable( + IN PVOID ImageBase +); + +NTSTATUS +NTAPI +TearDownGlobalMessageTable( + VOID +); + +NTSTATUS +NTAPI +GetCommandConsoleLaunchingPermission( + OUT PBOOLEAN Permission +); + +NTSTATUS +NTAPI +ImposeSacCmdServiceStartTypePolicy( + VOID +); + +NTSTATUS +NTAPI +RegisterBlueScreenMachineInformation( + VOID +); + +VOID +NTAPI +FreeMachineInformation( + VOID +); + +// +// DPC, Timer, Thread Callbacks +// +VOID +NTAPI +TimerDpcRoutine( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 +); + +// +// Custom SAC Heap Allocator Routines +// +PVOID +NTAPI +MyAllocatePool( + IN SIZE_T PoolSize, + IN ULONG Tag, + IN PCHAR File, + IN ULONG Line +); + +VOID +NTAPI +MyFreePool( + IN PVOID *Block +); + +// +// Connection Manager Routines +// +NTSTATUS +NTAPI +ConMgrInitialize( + VOID +); + +VOID +NTAPI +ConMgrWorkerProcessEvents( + IN PSAC_DEVICE_EXTENSION DeviceExtension +); + +NTSTATUS +NTAPI +ConMgrShutdown( + VOID +); + +BOOLEAN +NTAPI +ConMgrSimpleEventMessage( + IN ULONG MessageIndex, + IN BOOLEAN LockHeld +); + +BOOLEAN +NTAPI +SacPutSimpleMessage( + IN ULONG MessageIndex +); + +VOID +NTAPI +SacPutString( + IN PWCHAR String +); + +NTSTATUS +NTAPI +ConMgrWriteData( + IN PSAC_CHANNEL Channel, + IN PVOID Buffer, + IN ULONG BufferLength +); + +NTSTATUS +NTAPI +ConMgrFlushData( + IN PSAC_CHANNEL Channel +); + +BOOLEAN +NTAPI +ConMgrIsWriteEnabled( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ConMgrHandleEvent( + IN ULONG EventCode, + IN PSAC_CHANNEL Channel, + OUT PVOID Data +); + +// +// Channel Manager Routines +// +NTSTATUS +NTAPI +ChanMgrInitialize( + VOID +); + +NTSTATUS +NTAPI +ChanMgrShutdown( + VOID +); + +NTSTATUS +NTAPI +ChanMgrCreateChannel( + OUT PSAC_CHANNEL *Channel, + IN PSAC_CHANNEL_ATTRIBUTES Attributes +); + +NTSTATUS +NTAPI +ChanMgrGetByHandle( + IN SAC_CHANNEL_ID ChannelId, + OUT PSAC_CHANNEL* TargetChannel +); + +NTSTATUS +NTAPI +ChanMgrReleaseChannel( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ChanMgrGetNextActiveChannel( + IN PSAC_CHANNEL CurrentChannel, + IN PULONG TargetIndex, + OUT PSAC_CHANNEL *TargetChannel +); + +NTSTATUS +NTAPI +ChanMgrCloseChannel( + IN PSAC_CHANNEL Channel +); + +// +// Channel Routines +// +NTSTATUS +NTAPI +ChannelClose( + IN PSAC_CHANNEL Channel +); + +BOOLEAN +NTAPI +ChannelIsEqual( + IN PSAC_CHANNEL Channel, + IN PSAC_CHANNEL_ID ChannelId +); + +NTSTATUS +NTAPI +ChannelOWrite( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize +); + +NTSTATUS +NTAPI +ChannelOFlush( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ChannelSetRedrawEvent( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ChannelClearRedrawEvent( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ChannelHasRedrawEvent( + IN PSAC_CHANNEL Channel, + OUT PBOOLEAN Present +); + +BOOLEAN +NTAPI +ChannelIsActive( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +ChannelGetName( + IN PSAC_CHANNEL Channel, + OUT PWCHAR *Name +); + +BOOLEAN +NTAPI +ChannelIsEqual( + IN PSAC_CHANNEL Channel, + IN PSAC_CHANNEL_ID ChannelId +); + +NTSTATUS +NTAPI +ChannelCreate( + IN PSAC_CHANNEL Channel, + IN PSAC_CHANNEL_ATTRIBUTES Attributes, + IN SAC_CHANNEL_ID ChannelId +); + +NTSTATUS +NTAPI +ChannelDestroy( + IN PSAC_CHANNEL Channel +); + +// +// RAW Channel Table +// +NTSTATUS +NTAPI +RawChannelCreate( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +RawChannelDestroy( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +RawChannelORead( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + OUT PULONG ByteCount +); + +NTSTATUS +NTAPI +RawChannelOEcho( + IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length +); + +NTSTATUS +NTAPI +RawChannelOFlush( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +RawChannelOWrite( + IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length +); + +NTSTATUS +NTAPI +RawChannelIRead( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + IN PULONG ReturnBufferSize +); + +NTSTATUS +NTAPI +RawChannelIBufferIsFull( + IN PSAC_CHANNEL Channel, + OUT PBOOLEAN BufferStatus +); + +ULONG +NTAPI +RawChannelIBufferLength( + IN PSAC_CHANNEL Channel +); + +CHAR +NTAPI +RawChannelIReadLast( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +RawChannelIWrite( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize +); + +// +// Helper Routines +// +NTSTATUS +NTAPI +SerialBufferGetChar( + OUT PCHAR Char +); + +NTSTATUS +NTAPI +UTF8EncodeAndSend( + IN PWCHAR String +); + +NTSTATUS +NTAPI +TranslateMachineInformationXML( + IN PWCHAR *Buffer, + IN PWCHAR ExtraData +); + +PWCHAR +NTAPI +GetMessage( + IN ULONG MessageIndex +); + +BOOLEAN +NTAPI +VerifyEventWaitable( + IN HANDLE Handle, + OUT PVOID *WaitObject, + OUT PVOID *ActualWaitObject +); + +// +// SAC Command Functions +// +VOID +NTAPI +DoRebootCommand( + IN BOOLEAN Reboot +); + +// +// External data +// +extern ULONG SACDebug; +extern PSAC_MESSAGE_ENTRY GlobalMessageTable; +extern KMUTEX CurrentChannelLock; +extern LONG CurrentChannelRefCount; +extern PCHAR SerialPortBuffer; +extern PCHAR Utf8ConversionBuffer; +extern ULONG Utf8ConversionBufferSize; + +// +// Function to initailize a SAC Semaphore Lock +// +FORCEINLINE +VOID +SacInitializeLock(IN PSAC_CHANNEL_LOCK Lock) +{ + KeInitializeSemaphore(&Lock->Lock, 1, 1); +} + +// +// Function to acquire a SAC Semaphore Lock +// +FORCEINLINE +VOID +SacAcquireLock(IN PSAC_CHANNEL_LOCK Lock) +{ + KeWaitForSingleObject(&Lock->Lock, Executive, KernelMode, FALSE, NULL); + ASSERT(Lock->RefCount == 0); + _InterlockedIncrement(&Lock->RefCount); +} + +// +// Function to release a SAC Semaphore Lock +// +FORCEINLINE +VOID +SacReleaseLock(IN PSAC_CHANNEL_LOCK Lock) +{ + ASSERT(Lock->RefCount == 1); + _InterlockedDecrement(&Lock->RefCount); + KeReleaseSemaphore(&Lock->Lock, SEMAPHORE_INCREMENT, 1, FALSE); +} + +// +// Function to check if the SAC Mutex Lock is held +// +FORCEINLINE +VOID +SacAssertMutexLockHeld(VOID) +{ + ASSERT(CurrentChannelRefCount == 1); + ASSERT(KeReadStateMutex(&CurrentChannelLock) == 0); +} + +// +// Function to check if the SAC Mutex Lock is held +// +FORCEINLINE +VOID +SacInitializeMutexLock(VOID) +{ + KeInitializeMutex(&CurrentChannelLock, 0); + CurrentChannelRefCount = 0; +} + +// +// Function to acquire the SAC Mutex Lock +// +FORCEINLINE +VOID +SacAcquireMutexLock(VOID) +{ + KeWaitForSingleObject(&CurrentChannelLock, Executive, KernelMode, FALSE, NULL); + ASSERT(CurrentChannelRefCount == 0); + _InterlockedIncrement(&CurrentChannelRefCount); +} + +// +// Function to release the SAC Mutex Lock +// +FORCEINLINE +VOID +SacReleaseMutexLock(VOID) +{ + ASSERT(CurrentChannelRefCount == 1); + _InterlockedDecrement(&CurrentChannelRefCount); + KeReleaseMutex(&CurrentChannelLock, FALSE); +} + +// +// Locking Macros +// +#define ChannelLockCreates() SacAcquireLock(&ChannelCreateLock); +#define ChannelUnlockCreates() SacReleaseLock(&ChannelCreateLock); +#define ChannelLockOBuffer(x) SacAcquireLock(&x->ChannelOBufferLock); +#define ChannelUnlockOBuffer(x) SacReleaseLock(&x->ChannelOBufferLock); +#define ChannelLockIBuffer(x) SacAcquireLock(&x->ChannelIBufferLock); +#define ChannelUnlockIBuffer(x) SacReleaseLock(&x->ChannelIBufferLock); +#define ChannelLockAttributes(x) SacAcquireLock(&x->ChannelAttributeLock); +#define ChannelUnlockAttributes(x) SacReleaseLock(&x->ChannelAttributeLock); +#define ChannelSlotLock(x) SacAcquireLock(&ChannelSlotLock[x]); +#define ChannelSlotUnlock(x) SacReleaseLock(&ChannelSlotLock[x]); + +// +// Channel Accessors +// +FORCEINLINE +ULONG +ChannelGetFlags(IN PSAC_CHANNEL Channel) +{ + return Channel->Flags; +} + +FORCEINLINE +LONG +ChannelGetIndex(IN PSAC_CHANNEL Channel) +{ + /* Return the index of the channel */ + return Channel->Index; +} diff --git a/drivers/sac/driver/sacdrv.rc b/drivers/sac/driver/sacdrv.rc index ceb819a9005..1c1e27d36ec 100644 --- a/drivers/sac/driver/sacdrv.rc +++ b/drivers/sac/driver/sacdrv.rc @@ -1,5 +1,5 @@ /* - * PROJECT: ReactOS Boot Loader + * PROJECT: ReactOS Drivers * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: drivers/base/sac/driver/sacdrv.rc * PURPOSE: Resource File for EMS SAC Driver diff --git a/drivers/sac/driver/util.c b/drivers/sac/driver/util.c index b40f058c592..32daaac3bc3 100644 --- a/drivers/sac/driver/util.c +++ b/drivers/sac/driver/util.c @@ -1,18 +1,760 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/util.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/util.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/ #include "sacdrv.h" -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ -/* FUNCTIONS ******************************************************************/ +PCHAR Utf8ConversionBuffer; +ULONG Utf8ConversionBufferSize; +PSAC_MACHINE_INFO MachineInformation; +PVOID RequestSacCmdEventObjectBody; +PKEVENT RequestSacCmdEventWaitObjectBody; +PVOID RequestSacCmdSuccessEventObjectBody; +PKEVENT RequestSacCmdSuccessEventWaitObjectBody; +PVOID RequestSacCmdFailureEventObjectBody; +PKEVENT RequestSacCmdFailureEventWaitObjectBody; +PFILE_OBJECT ServiceProcessFileObject; +BOOLEAN HaveUserModeServiceCmdEventInfo; + +PSAC_MESSAGE_ENTRY GlobalMessageTable; +ULONG GlobalMessageTableCount; + +LONG SerialPortConsumerIndex, SerialPortProducerIndex; +PCHAR SerialPortBuffer; + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +NTAPI +SacTranslateUnicodeToUtf8(IN PWCHAR SourceBuffer, + IN ULONG SourceBufferLength, + OUT PCHAR DestinationBuffer, + IN ULONG DestinationBufferSize, + OUT PULONG UTF8Count, + OUT PULONG ProcessedCount) +{ + ASSERT(FALSE); + return FALSE; +} + +PWCHAR +NTAPI +GetMessage(IN ULONG MessageIndex) +{ + PSAC_MESSAGE_ENTRY MessageEntry; + ULONG i; + PWCHAR MessageData = NULL; + + /* Loop all cached messages */ + for (i = 0; i < GlobalMessageTableCount; i++) + { + /* Check if this one matches the index */ + MessageEntry = &GlobalMessageTable[i]; + if (MessageEntry->Index == MessageIndex) + { + /* It does, return the buffer */ + MessageData = MessageEntry->Buffer; + break; + } + } + + /* We should always find it */ + if (!MessageData) ASSERT(FALSE); + return MessageData; +} + +NTSTATUS +NTAPI +UTF8EncodeAndSend(IN PWCHAR String) +{ + ULONG ProcessedCount, Utf8Count, i; + NTSTATUS Status = STATUS_SUCCESS; + + /* Call the translator routine */ + if (SacTranslateUnicodeToUtf8(String, + wcslen(String), + Utf8ConversionBuffer, + Utf8ConversionBufferSize, + &Utf8Count, + &ProcessedCount)) + { + /* Loop every character */ + for (i = 0; i < Utf8Count; i++) + { + /* Send it to the terminal */ + Status = HeadlessDispatch(HeadlessCmdPutData, + &Utf8ConversionBuffer[i], + sizeof(Utf8ConversionBuffer[i]), + NULL, + NULL); + if (!NT_SUCCESS(Status)) break; + } + } + else + { + /* Conversion failed */ + Status = STATUS_UNSUCCESSFUL; + } + + /* All done */ + return Status; +} + +VOID +NTAPI +SacFormatMessage(IN PWCHAR FormattedString, + IN PWCHAR MessageString, + IN ULONG MessageSize) +{ + /* FIXME: For now don't format anything */ + wcsncpy(FormattedString, MessageString, MessageSize / sizeof(WCHAR)); +} + +NTSTATUS +NTAPI +PreloadGlobalMessageTable(IN PVOID ImageBase) +{ + NTSTATUS Status; + ULONG MessageId, TotalLength, TextSize, i; + PWCHAR StringBuffer; + PMESSAGE_RESOURCE_ENTRY MessageEntry; + PAGED_CODE(); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC PreloadGlobalMessageTable: Entering.\n"); + + /* Nothing to do if we already have a table */ + if (GlobalMessageTable) goto Exit; + + /* Loop through up to 200 messages */ + TotalLength = 0; + for (MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++) + { + /* Find this message ID in the string table*/ + Status = RtlFindMessage(ImageBase, + 11, + LANG_NEUTRAL, + MessageId, + &MessageEntry); + if (NT_SUCCESS(Status)) + { + /* Make sure it's Unicode */ + ASSERT(MessageEntry->Flags & MESSAGE_RESOURCE_UNICODE); + + /* Remove the space taken up by the OS header, and add our own */ + TotalLength += MessageEntry->Length - + FIELD_OFFSET(MESSAGE_RESOURCE_ENTRY, Text) + + sizeof(SAC_MESSAGE_ENTRY); + + /* One more in the table */ + GlobalMessageTableCount++; + } + } + + /* We should've found at least one message... */ + if (!TotalLength) + { + /* Bail out otherwise */ + SAC_DBG(SAC_DBG_INIT, "SAC PreloadGlobalMessageTable: No Messages.\n"); + Status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + /* Allocate space for the buffers and headers */ + GlobalMessageTable = SacAllocatePool(TotalLength, GLOBAL_BLOCK_TAG); + if (!GlobalMessageTable) + { + /* Bail out if we couldn't allocate it */ + Status = STATUS_NO_MEMORY; + goto Exit; + } + + /* All the buffers are going to be at the end of the table */ + StringBuffer = (PWCHAR)(&GlobalMessageTable[GlobalMessageTableCount]); + + /* Now loop over our entries again */ + for (i = 0, MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++) + { + /* Make sure the message is still there...! */ + Status = RtlFindMessage(ImageBase, + 11, + LANG_NEUTRAL, + MessageId, + &MessageEntry); + if (NT_SUCCESS(Status)) + { + /* Write the entry in the message table*/ + GlobalMessageTable[i].Index = MessageId; + GlobalMessageTable[i].Buffer = StringBuffer; + + /* The structure includes the size of the header, elide it */ + TextSize = MessageEntry->Length - + FIELD_OFFSET(MESSAGE_RESOURCE_ENTRY, Text); + + /* Format the message into the entry. It should be same or smaller */ + SacFormatMessage(StringBuffer, (PWCHAR)MessageEntry->Text, TextSize); + ASSERT((ULONG)(wcslen(StringBuffer)*sizeof(WCHAR)) <= TextSize); + + /* Move to the next buffer space */ + StringBuffer += TextSize; + + /* Move to the next entry, make sure the status is full success */ + i++; + Status = STATUS_SUCCESS; + } + } + +Exit: + /* All done, return the status code */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Exiting with status 0x%0x\n", Status); + return Status; +} + +NTSTATUS +NTAPI +TearDownGlobalMessageTable(VOID) +{ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Entering.\n"); + + /* Free the table if one existed */ + if (GlobalMessageTable) SacFreePool(GlobalMessageTable); + + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Exiting\n"); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +TranslateMachineInformationXML(IN PWCHAR *Buffer, + IN PWCHAR ExtraData) +{ + NTSTATUS Status; + ULONG Size; + PWCHAR p; + CHECK_PARAMETER1(Buffer); + + Status = STATUS_SUCCESS; + Size = wcslen(L"\r\n"); + + if (MachineInformation->MachineName) + { + Size += wcslen(MachineInformation->MachineName); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->MachineGuid) + { + Size += wcslen(MachineInformation->MachineGuid); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->ProcessorArchitecture) + { + Size += wcslen(MachineInformation->ProcessorArchitecture); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->MajorVersion) + { + Size += wcslen(MachineInformation->MajorVersion); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->BuildNumber) + { + Size += wcslen(MachineInformation->BuildNumber); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->ProductType) + { + Size += wcslen(MachineInformation->ProductType); + Size += wcslen(L"%s\r\n"); + } + + if (MachineInformation->ServicePack) + { + Size += wcslen(MachineInformation->ServicePack); + Size += wcslen(L"%s\r\n"); + } + + if (ExtraData) Size += wcslen(ExtraData); + + Size += wcslen(L"\r\n"); + + p = (PWCHAR)SacAllocatePool((Size + sizeof(ANSI_NULL)) * sizeof(WCHAR), GLOBAL_BLOCK_TAG); + + *Buffer = p; + if (!p) return STATUS_NO_MEMORY; + + Size = wcslen(L"\r\n"); + wcscpy(p, L"\r\n"); + + p += Size; + + if (MachineInformation->MachineName) + { + p += swprintf(p, L"%s\r\n", MachineInformation->MachineName); + } + + if (MachineInformation->MachineGuid) + { + p += swprintf(p, L"%s\r\n", MachineInformation->MachineGuid); + } + + if (MachineInformation->ProcessorArchitecture) + { + p += swprintf(p, L"%s\r\n", MachineInformation->ProcessorArchitecture); + } + + if (MachineInformation->MajorVersion) + { + p += swprintf(p, L"%s\r\n", MachineInformation->MajorVersion); + } + + if (MachineInformation->BuildNumber) + { + p += swprintf(p, L"%s\r\n", MachineInformation->BuildNumber); + } + + if (MachineInformation->ProductType) + { + p += swprintf(p, L"%s\r\n", MachineInformation->ProductType); + } + + if (MachineInformation->ServicePack) + { + p += swprintf(p, L"%s\r\n", MachineInformation->ServicePack); + } + + if (ExtraData) + { + Size = wcslen(ExtraData); + wcscpy(p, ExtraData); + p += Size; + } + + wcscpy(p, L"\r\n"); + ASSERT((((ULONG) wcslen(*Buffer) + 1) * sizeof(WCHAR)) <= Size); + return Status; +} + +VOID +NTAPI +InitializeMachineInformation(VOID) +{ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Entering.\n"); + + /* FIXME: TODO */ + MachineInformation = NULL; + ASSERT(FALSE); + + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Exiting with error.\n"); +} + +NTSTATUS +NTAPI +GetRegistryValueBuffer(IN PCWSTR KeyName, + IN PWCHAR ValueName, + IN PKEY_VALUE_PARTIAL_INFORMATION* Buffer) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING DestinationString; + HANDLE Handle; + SIZE_T ResultLength = 0; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: Entering.\n"); + CHECK_PARAMETER1(KeyName); + CHECK_PARAMETER2(ValueName); + + /* Open the specified key */ + RtlInitUnicodeString(&DestinationString, KeyName); + InitializeObjectAttributes(&ObjectAttributes, + &DestinationString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ZwOpenKey(&Handle, + KEY_WRITE | SYNCHRONIZE | KEY_READ, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + /* Bail out on failure */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: failed ZwOpenKey: %X.\n", Status); + return Status; + } + + /* Query the size of the key */ + RtlInitUnicodeString(&DestinationString, ValueName); + Status = ZwQueryValueKey(Handle, + &DestinationString, + KeyValuePartialInformation, + NULL, + 0, + &ResultLength); + if (!ResultLength) return Status; + + /* Allocate the buffer for the partial info structure and our integer data */ + ResultLength += sizeof(ULONG); + *Buffer = SacAllocatePool(ResultLength, GLOBAL_BLOCK_TAG); + if (!*Buffer) + { + SAC_DBG(1, "SAC GetRegistryValueBuffer: failed allocation\n"); + return Status; + } + + /* Now read the data */ + Status = ZwQueryValueKey(Handle, + &DestinationString, + KeyValuePartialInformation, + *Buffer, + ResultLength, + &ResultLength); + if (!NT_SUCCESS(Status)) + { + /* Free the buffer if we couldn't read the data */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: failed ZwQueryValueKey: %X.\n", Status); + SacFreePool(*Buffer); + } + + /* Return the result */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Exiting.\n"); + return Status; +} + +NTSTATUS +NTAPI +SetRegistryValue(IN PCWSTR KeyName, + IN PWCHAR ValueName, + IN ULONG Type, + IN PVOID Data, + IN ULONG DataSize) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING DestinationString; + HANDLE Handle; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Entering.\n"); + CHECK_PARAMETER1(KeyName); + CHECK_PARAMETER2(ValueName); + CHECK_PARAMETER4(Data); + + /* Open the specified key */ + RtlInitUnicodeString(&DestinationString, KeyName); + InitializeObjectAttributes(&ObjectAttributes, + &DestinationString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ZwOpenKey(&Handle, + KEY_WRITE | SYNCHRONIZE | KEY_READ, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + /* Bail out on failure */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: failed ZwOpenKey: %X.\n", Status); + return Status; + } + + /* Set the specified value */ + RtlInitUnicodeString(&DestinationString, ValueName); + Status = ZwSetValueKey(Handle, &DestinationString, 0, Type, Data, DataSize); + if (!NT_SUCCESS(Status)) + { + /* Print error on failure */ + SAC_DBG(1, "SAC SetRegistryValue: failed ZwSetValueKey: %X.\n", Status); + } + + /* Close the handle and exit */ + NtClose(Handle); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Exiting.\n"); + return Status; +} + +NTSTATUS +NTAPI +CopyRegistryValueData(IN PULONG* Buffer, + IN PKEY_VALUE_PARTIAL_INFORMATION PartialInfo) +{ + NTSTATUS Status = STATUS_SUCCESS; + CHECK_PARAMETER1(Buffer); + CHECK_PARAMETER2(PartialInfo); + + /* Allocate space for registry data */ + *Buffer = SacAllocatePool(PartialInfo->DataLength, GLOBAL_BLOCK_TAG); + if (*Buffer) + { + /* Copy the data into the buffer */ + RtlCopyMemory(*Buffer, PartialInfo->Data, PartialInfo->DataLength); + } + else + { + /* Set the correct error code */ + SAC_DBG(SAC_DBG_UTIL, "SAC CopyRegistryValueBuffer: Failed ALLOCATE.\n"); + Status = STATUS_NO_MEMORY; + } + + /* Return the result */ + return Status; +} + +NTSTATUS +NTAPI +GetCommandConsoleLaunchingPermission(OUT PBOOLEAN Permission) +{ + NTSTATUS Status; + PKEY_VALUE_PARTIAL_INFORMATION Dummy; + + /* Assume success and read the key */ + *Permission = TRUE; + Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacdrv", + L"DisableCmdSessions", + &Dummy); + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + /* The default is success */ + Status = STATUS_SUCCESS; + } + else + { + /* Only if the key is present and set, do we disable permission */ + if (NT_SUCCESS(Status)) *Permission = FALSE; + } + + /* Return status */ + return Status; +} + +NTSTATUS +NTAPI +ImposeSacCmdServiceStartTypePolicy(VOID) +{ + NTSTATUS Status; + PKEY_VALUE_PARTIAL_INFORMATION Buffer = NULL; + PULONG Data; + + /* Read the service start type*/ + Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacsvr", + L"Start", + &Buffer); + if (!NT_SUCCESS(Status)) return Status; + + /* If there's no start type, fail, as this is unusual */ + if (!Buffer) return STATUS_UNSUCCESSFUL; + + /* Read the value */ + Status = CopyRegistryValueData(&Data, Buffer); + SacFreePool(Buffer); + if (!NT_SUCCESS(Status)) return Status; + + /* Check what the current start type is */ + switch (*Data) + { + /* It's boot, system, or disabled */ + case 1: + case 2: + case 4: + /* Leave it as is */ + return Status; + + case 3: + + /* It's set to automatic, set it to system instead */ + *Data = 2; + Status = SetRegistryValue(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacsvr", + L"Start", + REG_DWORD, + Data, + sizeof(ULONG)); + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC ImposeSacCmdServiceStartTypePolicy: Failed SetRegistryValue: %X\n", Status); + } + break; + + default: + ASSERT(FALSE); + } + + return Status; +} + +VOID +NTAPI +InitializeCmdEventInfo(VOID) +{ + /* Check if we were already initailized */ + if (HaveUserModeServiceCmdEventInfo) + { + /* Full state expected */ + ASSERT(RequestSacCmdEventObjectBody); + ASSERT(RequestSacCmdSuccessEventObjectBody); + ASSERT(RequestSacCmdFailureEventObjectBody); + + /* Dereference each wait object in turn */ + if (RequestSacCmdEventObjectBody) + { + ObDereferenceObject(RequestSacCmdEventObjectBody); + } + + if (RequestSacCmdSuccessEventObjectBody) + { + ObDereferenceObject(RequestSacCmdSuccessEventObjectBody); + } + + if (RequestSacCmdFailureEventObjectBody) + { + ObDereferenceObject(RequestSacCmdFailureEventObjectBody); + } + } + + /* Claer everything */ + RequestSacCmdEventObjectBody = NULL; + RequestSacCmdEventWaitObjectBody = NULL; + RequestSacCmdSuccessEventObjectBody = NULL; + RequestSacCmdSuccessEventWaitObjectBody = NULL; + RequestSacCmdFailureEventObjectBody = NULL; + RequestSacCmdFailureEventWaitObjectBody = NULL; + ServiceProcessFileObject = NULL; + + /* Reset state */ + HaveUserModeServiceCmdEventInfo = FALSE; +} + +NTSTATUS +NTAPI +RegisterBlueScreenMachineInformation(VOID) +{ + PWCHAR XmlBuffer; + PHEADLESS_BLUE_SCREEN_DATA BsBuffer; + ULONG Length, HeaderLength, TotalLength; + NTSTATUS Status; + ULONG i; + + /* Create the XML buffer and make sure it's OK */ + Status = TranslateMachineInformationXML(&XmlBuffer, NULL); + CHECK_PARAMETER_WITH_STATUS(NT_SUCCESS(Status), Status); + CHECK_PARAMETER_WITH_STATUS(XmlBuffer, STATUS_UNSUCCESSFUL); + + /* Compute the sizes and allocate a buffer for it */ + Length = wcslen(XmlBuffer); + HeaderLength = strlen("MACHINEINFO"); + TotalLength = HeaderLength + + Length + + sizeof(*BsBuffer) + + 2 * sizeof(ANSI_NULL); + BsBuffer = SacAllocatePool(TotalLength, GLOBAL_BLOCK_TAG); + CHECK_PARAMETER_WITH_STATUS(BsBuffer, STATUS_NO_MEMORY); + + /* Copy the XML property name */ + strcpy((PCHAR)BsBuffer->XMLData, "MACHINEINFO"); + BsBuffer->Property = (PUCHAR)HeaderLength + sizeof(ANSI_NULL); + + /* Copy the data and NULL-terminate it */ + for (i = 0; i < Length; i++) + { + BsBuffer->XMLData[HeaderLength + sizeof(ANSI_NULL) + i] = XmlBuffer[i]; + } + BsBuffer->XMLData[HeaderLength + sizeof(ANSI_NULL) + i] = ANSI_NULL; + + /* Let the OS save the buffer for later */ + Status = HeadlessDispatch(HeadlessCmdSetBlueScreenData, + BsBuffer, + TotalLength, + NULL, + NULL); + + /* Failure or not, we don't need this anymore */ + SacFreePool(BsBuffer); + SacFreePool(XmlBuffer); + + /* Return the result */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information: Exiting.\n"); + return Status; +} + +VOID +NTAPI +FreeMachineInformation(VOID) +{ + ASSERT(MachineInformation); + + /* Free every cached string of machine information */ + if (MachineInformation->MachineName) SacFreePool(MachineInformation); + if (MachineInformation->MachineGuid) SacFreePool(MachineInformation->MachineGuid); + if (MachineInformation->ProcessorArchitecture) SacFreePool(MachineInformation->ProcessorArchitecture); + if (MachineInformation->MajorVersion) SacFreePool(MachineInformation->MajorVersion); + if (MachineInformation->BuildNumber) SacFreePool(MachineInformation->BuildNumber); + if (MachineInformation->ProductType) SacFreePool(MachineInformation->ProductType); + if (MachineInformation->ServicePack) SacFreePool(MachineInformation->ServicePack); +} + +BOOLEAN +NTAPI +VerifyEventWaitable(IN HANDLE Handle, + OUT PVOID *WaitObject, + OUT PVOID *ActualWaitObject) +{ + PVOID Object; + NTSTATUS Status; + POBJECT_TYPE ObjectType; + + /* Reference the object */ + Status = ObReferenceObjectByHandle(Handle, + EVENT_ALL_ACCESS, + NULL, + KernelMode, + &Object, + NULL); + *WaitObject = Object; + if (!NT_SUCCESS(Status)) + { + SAC_DBG(SAC_DBG_INIT, "SAC VerifyEventWaitable: Unable to reference event object (%lx)\n", Status); + return FALSE; + } + + /* Check if the object itself is NOT being used */ + ObjectType = OBJECT_TO_OBJECT_HEADER(Object)->Type; + if (ObjectType->TypeInfo.UseDefaultObject == FALSE) + { + /* Get the actual object that's being used for the wait */ + *ActualWaitObject = (PVOID)((ULONG_PTR)Object + + (ULONG_PTR)ObjectType->DefaultObject); + return TRUE; + } + + /* Drop the reference we took */ + SAC_DBG(SAC_DBG_INIT, "SAC VerifyEventWaitable: event object not waitable!\n"); + ObDereferenceObject(*WaitObject); + return FALSE; +} + +NTSTATUS +NTAPI +SerialBufferGetChar(OUT PCHAR Char) +{ + /* Check if nothing's been produced yet */ + if (SerialPortConsumerIndex == SerialPortProducerIndex) + { + return STATUS_NO_DATA_DETECTED; + } + + /* Consume the produced character and clear it*/ + *Char = SerialPortBuffer[SerialPortConsumerIndex]; + SerialPortBuffer[SerialPortConsumerIndex] = ANSI_NULL; + + /* Advance the index and return success */ + _InterlockedExchange(&SerialPortConsumerIndex, + (SerialPortConsumerIndex + 1) & + (SAC_SERIAL_PORT_BUFFER_SIZE - 1)); + return STATUS_SUCCESS; +} ULONG ConvertAnsiToUnicode( @@ -32,24 +774,6 @@ IsCmdEventRegistrationProcess( return FALSE; } -VOID -InitializeCmdEventInfo( - VOID - ) -{ - -} - -BOOLEAN -VerifyEventWaitable( - IN PVOID Object, - OUT PVOID *WaitObject, - OUT PVOID *ActualWaitObject - ) -{ - return FALSE; -} - NTSTATUS InvokeUserModeService( VOID @@ -58,32 +782,6 @@ InvokeUserModeService( return STATUS_NOT_IMPLEMENTED; } -VOID -SacFormatMessage( - IN PWCHAR FormattedString, - IN PWCHAR MessageString, - IN ULONG MessageSize - ) -{ - -} - -NTSTATUS -TearDownGlobalMessageTable( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -PWCHAR -GetMessage( - IN ULONG MessageIndex - ) -{ - return NULL; -} - BOOLEAN SacTranslateUtf8ToUnicode( IN CHAR Utf8Char, @@ -94,50 +792,6 @@ SacTranslateUtf8ToUnicode( return FALSE; } -BOOLEAN -SacTranslateUnicodeToUtf8( - IN PWCHAR SourceBuffer, - IN ULONG SourceBufferLength, - OUT PCHAR DestinationBuffer, - IN ULONG DestinationBufferSize, - IN ULONG UTF8Count, - OUT PULONG ProcessedCount - ) -{ - return FALSE; -} - -NTSTATUS -GetRegistryValueBuffer( - IN PCWSTR KeyName, - IN PWCHAR ValueName, - IN PKEY_VALUE_PARTIAL_INFORMATION ValueBuffer - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -SetRegistryValue( - IN PCWSTR KeyName, - IN PWCHAR ValueName, - IN ULONG Type, - IN PVOID Data, - IN ULONG DataSize - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -CopyRegistryValueData( - IN PVOID Dest, - IN PKEY_VALUE_PARTIAL_INFORMATION ValueBuffer - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS TranslateMachineInformationText( IN PWCHAR Buffer) @@ -145,55 +799,6 @@ TranslateMachineInformationText( return STATUS_NOT_IMPLEMENTED; } -NTSTATUS -TranslateMachineInformationXML( - IN PWCHAR Buffer, - IN PWCHAR ExtraData - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -RegisterBlueScreenMachineInformation( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -VOID -FreeMachineInformation( - VOID - ) -{ - -} - -NTSTATUS -SerialBufferGetChar( - OUT PCHAR Char - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -GetCommandConsoleLaunchingPermission( - OUT PBOOLEAN Permission - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -ImposeSacCmdServiceStartTypePolicy( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS CopyAndInsertStringAtInterval( IN PWCHAR SourceStr, @@ -229,11 +834,3 @@ UnregisterSacCmdEvent( { return STATUS_NOT_IMPLEMENTED; } - -NTSTATUS -UTF8EncodeAndSend( - IN PWCHAR String - ) -{ - return STATUS_NOT_IMPLEMENTED; -} diff --git a/include/crt/sec_api/time_s.h b/include/crt/sec_api/time_s.h index fdcf1a848b8..5421831262a 100644 --- a/include/crt/sec_api/time_s.h +++ b/include/crt/sec_api/time_s.h @@ -3,6 +3,7 @@ * This file is part of the w64 mingw-runtime package. * No warranty is given; refer to the file DISCLAIMER within this package. */ + #ifndef _TIME_H__S #define _TIME_H__S @@ -14,22 +15,110 @@ extern "C" { #endif - _CRTIMP errno_t __cdecl _ctime32_s(char *_Buf,size_t _SizeInBytes,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _gmtime32_s(struct tm *_Tm,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _localtime32_s(struct tm *_Tm,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _strdate_s(char *_Buf,size_t _SizeInBytes); - _CRTIMP errno_t __cdecl _strtime_s(char *_Buf ,size_t _SizeInBytes); - _CRTIMP errno_t __cdecl _ctime64_s(char *_Buf,size_t _SizeInBytes,const __time64_t *_Time); - _CRTIMP errno_t __cdecl _gmtime64_s(struct tm *_Tm,const __time64_t *_Time); - _CRTIMP errno_t __cdecl _localtime64_s(struct tm *_Tm,const __time64_t *_Time); + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _ctime32_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(26) char *_Buf, + _In_ size_t _SizeInBytes, + _In_ const __time32_t *_Time); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _gmtime32_s( + _In_ struct tm *_Tm, + _In_ const __time32_t *_Time); + + _CRTIMP + errno_t + __cdecl + _localtime32_s( + _Out_ struct tm *_Tm, + _In_ const __time32_t *_Time); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _strdate_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf, + _In_range_(>= , 9) size_t _SizeInBytes); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _strtime_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf, + _In_range_(>= , 9) size_t _SizeInBytes); + + _CRTIMP + errno_t + __cdecl + _ctime64_s( + _Out_writes_z_(_SizeInBytes) char *_Buf, + _In_ size_t _SizeInBytes, + _In_ const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _gmtime64_s( + _Out_ struct tm *_Tm, + _In_ const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _localtime64_s( + _Out_ struct tm *_Tm, + _In_ const __time64_t *_Time); #ifndef _WTIME_S_DEFINED #define _WTIME_S_DEFINED - _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); - _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _wasctime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_range_(>= , 26) size_t _SizeInWords, + _In_ const struct tm *_Tm); + + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _wctime32_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time32_t *_Time); + + _CRTIMP + errno_t + __cdecl + _wstrdate_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_ size_t _SizeInWords); + + _CRTIMP + errno_t + __cdecl + _wstrtime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_range_(>= , 9) size_t _SizeInWords); + + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _wctime64_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time64_t *_Time); #if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL) #define _INC_WTIME_S_INL @@ -38,7 +127,8 @@ extern "C" { __CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s(_Buffer,_SizeInWords,_Time); } #endif #endif -#endif + +#endif /* _WTIME_S_DEFINED */ #ifndef RC_INVOKED #ifdef _USE_32BIT_TIME_T @@ -52,5 +142,6 @@ __CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { r } #endif -#endif -#endif +#endif /* MINGW_HAS_SECURE_API */ + +#endif /* _TIME_H__S */ diff --git a/include/crt/sec_api/wchar_s.h b/include/crt/sec_api/wchar_s.h index 5ce967b7cab..9788be57359 100644 --- a/include/crt/sec_api/wchar_s.h +++ b/include/crt/sec_api/wchar_s.h @@ -3,6 +3,7 @@ * This file is part of the w64 mingw-runtime package. * No warranty is given; refer to the file DISCLAIMER within this package. */ + #ifndef _INC_WCHAR_S #define _INC_WCHAR_S @@ -16,100 +17,648 @@ extern "C" { #ifndef _WIO_S_DEFINED #define _WIO_S_DEFINED - _CRTIMP errno_t __cdecl _waccess_s(const wchar_t *_Filename,int _AccessMode); - _CRTIMP errno_t __cdecl _wmktemp_s(wchar_t *_TemplateName,size_t _SizeInWords); -#endif + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _waccess_s( + _In_z_ const wchar_t *_Filename, + _In_ int _AccessMode); + + _CRTIMP + errno_t + __cdecl + _wmktemp_s( + _Inout_updates_z_(_SizeInWords) wchar_t *_TemplateName, + _In_ size_t _SizeInWords); + +#endif /* _WIO_S_DEFINED */ #ifndef _WCONIO_S_DEFINED #define _WCONIO_S_DEFINED - _CRTIMP errno_t __cdecl _cgetws_s(wchar_t *_Buffer,size_t _SizeInWords,size_t *_SizeRead); - _CRTIMP int __cdecl _cwprintf_s(const wchar_t *_Format,...); - _CRTIMP int __cdecl _cwscanf_s(const wchar_t *_Format,...); - _CRTIMP int __cdecl _cwscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vcwprintf_s(const wchar_t *_Format,va_list _ArgList); - _CRTIMP int __cdecl _cwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vcwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); -#endif + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _cgetws_s( + _Out_writes_to_(_SizeInWords, *_SizeRead) wchar_t *_Buffer, + _In_ size_t _SizeInWords, + _Out_ size_t *_SizeRead); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _cwprintf_s( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _cwscanf_s( + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _cwscanf_s_l( + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vcwprintf_s( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + va_list _ArgList); + + _CRTIMP + int + __cdecl + _cwprintf_s_l( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _CRTIMP + int + __cdecl + _vcwprintf_s_l( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList); + +#endif /* _WCONIO_S_DEFINED */ #ifndef _WSTDIO_S_DEFINED #define _WSTDIO_S_DEFINED - _CRTIMP wchar_t *__cdecl _getws_s(wchar_t *_Str,size_t _SizeInWords); - int __cdecl fwprintf_s(FILE *_File,const wchar_t *_Format,...); - int __cdecl wprintf_s(const wchar_t *_Format,...); - int __cdecl vfwprintf_s(FILE *_File,const wchar_t *_Format,va_list _ArgList); - int __cdecl vwprintf_s(const wchar_t *_Format,va_list _ArgList); - int __cdecl swprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,...); - int __cdecl vswprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList); - _CRTIMP int __cdecl _snwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,...); - _CRTIMP int __cdecl _vsnwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList); - _CRTIMP int __cdecl _wprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); - _CRTIMP int __cdecl _fwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vfwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); - _CRTIMP int __cdecl _swprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vswprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); - _CRTIMP int __cdecl _snwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _vsnwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); - _CRTIMP int __cdecl _fwscanf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _swscanf_s_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _snwscanf_s(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...); - _CRTIMP int __cdecl _snwscanf_s_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP int __cdecl _wscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...); - _CRTIMP errno_t __cdecl _wfopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode); - _CRTIMP errno_t __cdecl _wfreopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile); - _CRTIMP errno_t __cdecl _wtmpnam_s(wchar_t *_DstBuf,size_t _SizeInWords); -#endif + + _Check_return_opt_ + _CRTIMP + wchar_t * + __cdecl + _getws_s( + _Out_writes_z_(_SizeInWords) wchar_t *_Str, + _In_ size_t _SizeInWords); + + _Check_return_opt_ + int + __cdecl + fwprintf_s( + _Inout_ FILE *_File, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + int + __cdecl + wprintf_s( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + int + __cdecl + vfwprintf_s( + _Inout_ FILE *_File, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + va_list _ArgList); + + _Check_return_opt_ + int + __cdecl + vwprintf_s( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + va_list _ArgList); + + int + __cdecl + swprintf_s( + _Out_writes_z_(_SizeInWords) wchar_t *_Dst, + _In_ size_t _SizeInWords, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + ...); + + int + __cdecl + vswprintf_s( + _Out_writes_z_(_SizeInWords) wchar_t *_Dst, + _In_ size_t _SizeInWords, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _snwprintf_s( + _Out_writes_z_(_DstSizeInWords) wchar_t *_DstBuf, + _In_ size_t _DstSizeInWords, + _In_ size_t _MaxCount, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vsnwprintf_s( + _Out_writes_z_(_DstSizeInWords) wchar_t *_DstBuf, + _In_ size_t _DstSizeInWords, + _In_ size_t _MaxCount, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _wprintf_s_l( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vwprintf_s_l( + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _fwprintf_s_l( + _Inout_ FILE *_File, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vfwprintf_s_l( + _Inout_ FILE *_File, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _swprintf_s_l( + _Out_writes_z_(_DstSize) wchar_t *_DstBuf, + _In_ size_t _DstSize, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vswprintf_s_l( + _Out_writes_z_(_DstSize) wchar_t *_DstBuf, + _In_ size_t _DstSize, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _snwprintf_s_l( + _Out_writes_z_(_DstSize) wchar_t *_DstBuf, + _In_ size_t _DstSize, + _In_ size_t _MaxCount, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _vsnwprintf_s_l( + _Out_writes_z_(_DstSize) wchar_t *_DstBuf, + _In_ size_t _DstSize, + _In_ size_t _MaxCount, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _fwscanf_s_l( + _Inout_ FILE *_File, + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _swscanf_s_l( + _In_z_ const wchar_t *_Src, + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _snwscanf_s( + _In_reads_(_MaxCount) _Pre_z_ const wchar_t *_Src, + _In_ size_t _MaxCount, + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _snwscanf_s_l( + _In_reads_(_MaxCount) _Pre_z_ const wchar_t *_Src, + _In_ size_t _MaxCount, + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_opt_ + _CRTIMP + int + __cdecl + _wscanf_s_l( + _In_z_ _Scanf_s_format_string_ const wchar_t *_Format, + _In_opt_ _locale_t _Locale, + ...); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wfopen_s( + _Outptr_result_maybenull_ FILE **_File, + _In_z_ const wchar_t *_Filename, + _In_z_ const wchar_t *_Mode); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wfreopen_s( + _Outptr_result_maybenull_ FILE **_File, + _In_z_ const wchar_t *_Filename, + _In_z_ const wchar_t *_Mode, + _Inout_ FILE *_OldFile); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wtmpnam_s( + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords); + +#endif /* _WSTDIO_S_DEFINED */ #ifndef _WSTDLIB_S_DEFINED #define _WSTDLIB_S_DEFINED - _CRTIMP errno_t __cdecl _itow_s (int _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); - _CRTIMP errno_t __cdecl _ltow_s (long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); - _CRTIMP errno_t __cdecl _ultow_s (unsigned long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); - _CRTIMP errno_t __cdecl _wgetenv_s(size_t *_ReturnSize,wchar_t *_DstBuf,size_t _DstSizeInWords,const wchar_t *_VarName); - _CRTIMP errno_t __cdecl _wdupenv_s(wchar_t **_Buffer,size_t *_BufferSizeInWords,const wchar_t *_VarName); - _CRTIMP errno_t __cdecl _i64tow_s(__int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); - _CRTIMP errno_t __cdecl _ui64tow_s(unsigned __int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); -#endif + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _itow_s( + _In_ int _Val, + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords, + _In_ int _Radix); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _ltow_s( + _In_ long _Val, + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords, + _In_ int _Radix); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _ultow_s( + _In_ unsigned long _Val, + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords, + _In_ int _Radix); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wgetenv_s( + _Out_ size_t *_ReturnSize, + _Out_writes_z_(_DstSizeInWords) wchar_t *_DstBuf, + _In_ size_t _DstSizeInWords, + _In_z_ const wchar_t *_VarName); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wdupenv_s( + _Outptr_result_buffer_maybenull_(*_BufferSizeInWords) _Deref_post_z_ wchar_t **_Buffer, + _Out_opt_ size_t *_BufferSizeInWords, + _In_z_ const wchar_t *_VarName); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _i64tow_s( + _In_ __int64 _Val, + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords, + _In_ int _Radix); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _ui64tow_s( + _In_ unsigned __int64 _Val, + _Out_writes_z_(_SizeInWords) wchar_t *_DstBuf, + _In_ size_t _SizeInWords, + _In_ int _Radix); + +#endif /* _WSTDLIB_S_DEFINED */ #ifndef _POSIX_ #ifndef _WSTDLIBP_S_DEFINED #define _WSTDLIBP_S_DEFINED - _CRTIMP errno_t __cdecl _wmakepath_s(wchar_t *_PathResult,size_t _SizeInWords,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext); - _CRTIMP errno_t __cdecl _wputenv_s(const wchar_t *_Name,const wchar_t *_Value); - _CRTIMP errno_t __cdecl _wsearchenv_s(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wsplitpath_s(const wchar_t *_FullPath,wchar_t *_Drive,size_t _DriveSizeInWords,wchar_t *_Dir,size_t _DirSizeInWords,wchar_t *_Filename,size_t _FilenameSizeInWords,wchar_t *_Ext,size_t _ExtSizeInWords); -#endif -#endif + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wmakepath_s( + _Out_writes_z_(_SizeInBytes) wchar_t *_PathResult, + _In_ size_t _SizeInWords, + _In_opt_z_ const wchar_t *_Drive, + _In_opt_z_ const wchar_t *_Dir, + _In_opt_z_ const wchar_t *_Filename, + _In_opt_z_ const wchar_t *_Ext); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wputenv_s( + _In_z_ const wchar_t *_Name, + _In_z_ const wchar_t *_Value); + + _CRTIMP + errno_t + __cdecl + _wsearchenv_s( + _In_z_ const wchar_t *_Filename, + _In_z_ const wchar_t *_EnvVar, + _Out_writes_z_(_SizeInWords) wchar_t *_ResultPath, + _In_ size_t _SizeInWords); + + _CRTIMP + errno_t + __cdecl + _wsplitpath_s( + _In_z_ const wchar_t *_FullPath, + _Out_writes_opt_z_(_DriveSizeInWords) wchar_t *_Drive, + _In_ size_t _DriveSizeInWords, + _Out_writes_opt_z_(_DirSizeInWords) wchar_t *_Dir, + _In_ size_t _DirSizeInWords, + _Out_writes_opt_z_(_FilenameSizeInWords) wchar_t *_Filename, + _In_ size_t _FilenameSizeInWords, + _Out_writes_opt_z_(_ExtSizeInWords) wchar_t *_Ext, + _In_ size_t _ExtSizeInWords); + +#endif /* _WSTDLIBP_S_DEFINED */ +#endif /* _POSIX_ */ #ifndef _WSTRING_S_DEFINED #define _WSTRING_S_DEFINED - _CRTIMP wchar_t *__cdecl wcstok_s(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context); - _CRTIMP errno_t __cdecl _wcserror_s(wchar_t *_Buf,size_t _SizeInWords,int _ErrNum); - _CRTIMP errno_t __cdecl __wcserror_s(wchar_t *_Buffer,size_t _SizeInWords,const wchar_t *_ErrMsg); - _CRTIMP errno_t __cdecl _wcsnset_s(wchar_t *_Dst,size_t _DstSizeInWords,wchar_t _Val,size_t _MaxCount); - _CRTIMP errno_t __cdecl _wcsset_s(wchar_t *_Str,size_t _SizeInWords,wchar_t _Val); - _CRTIMP errno_t __cdecl _wcslwr_s(wchar_t *_Str,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wcslwr_s_l(wchar_t *_Str,size_t _SizeInWords,_locale_t _Locale); - _CRTIMP errno_t __cdecl _wcsupr_s(wchar_t *_Str,size_t _Size); - _CRTIMP errno_t __cdecl _wcsupr_s_l(wchar_t *_Str,size_t _Size,_locale_t _Locale); - _CRTIMP errno_t __cdecl wcsncat_s(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount); - _CRTIMP errno_t __cdecl _wcsncat_s_l(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount,_locale_t _Locale); - _CRTIMP errno_t __cdecl wcsncpy_s(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount); - _CRTIMP errno_t __cdecl _wcsncpy_s_l(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount,_locale_t _Locale); - _CRTIMP wchar_t *__cdecl _wcstok_s_l(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context,_locale_t _Locale); - _CRTIMP errno_t __cdecl _wcsset_s_l(wchar_t *_Str,size_t _SizeInChars,unsigned int _Val,_locale_t _Locale); - _CRTIMP errno_t __cdecl _wcsnset_s_l(wchar_t *_Str,size_t _SizeInChars,unsigned int _Val, size_t _Count,_locale_t _Locale); + _Check_return_ + _CRTIMP + wchar_t * + __cdecl + wcstok_s( + _Inout_opt_z_ wchar_t *_Str, + _In_z_ const wchar_t *_Delim, + _Inout_ _Deref_prepost_opt_z_ wchar_t **_Context); -#endif + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcserror_s( + _Out_writes_opt_z_(_SizeInWords) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ int _ErrNum); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + __wcserror_s( + _Out_writes_opt_z_(_SizeInWords) wchar_t *_Buffer, + _In_ size_t _SizeInWords, + _In_z_ const wchar_t *_ErrMsg); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsnset_s( + _Inout_updates_z_(_DstSizeInWords) wchar_t *_Dst, + _In_ size_t _DstSizeInWords, + wchar_t _Val, + _In_ size_t _MaxCount); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsset_s( + _Inout_updates_z_(_SizeInWords) wchar_t *_Str, + _In_ size_t _SizeInWords, + wchar_t _Val); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcslwr_s( + _Inout_updates_z_(_SizeInWords) wchar_t *_Str, + _In_ size_t _SizeInWords); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcslwr_s_l( + _Inout_updates_z_(_SizeInWords) wchar_t *_Str, + _In_ size_t _SizeInWords, + _In_opt_ _locale_t _Locale); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsupr_s( + _Inout_updates_z_(_Size) wchar_t *_Str, + _In_ size_t _Size); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsupr_s_l( + _Inout_updates_z_(_Size) wchar_t *_Str, + _In_ size_t _Size, + _In_opt_ _locale_t _Locale); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + wcsncat_s( + _Inout_updates_z_(_DstSizeInChars) wchar_t *_Dst, + _In_ size_t _DstSizeInChars, + _In_z_ const wchar_t *_Src, + _In_ size_t _MaxCount); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsncat_s_l( + _Inout_updates_z_(_DstSizeInChars) wchar_t *_Dst, + _In_ size_t _DstSizeInChars, + _In_z_ const wchar_t *_Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + wcsncpy_s( + _Out_writes_z_(_DstSizeInChars) wchar_t *_Dst, + _In_ size_t _DstSizeInChars, + _In_z_ const wchar_t *_Src, + _In_ size_t _MaxCount); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _wcsncpy_s_l( + _Out_writes_z_(_DstSizeInChars) wchar_t *_Dst, + _In_ size_t _DstSizeInChars, + _In_z_ const wchar_t *_Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _CRTIMP + wchar_t * + __cdecl + _wcstok_s_l( + wchar_t *_Str, + const wchar_t *_Delim, + wchar_t **_Context, + _locale_t _Locale); + + _CRTIMP + errno_t + __cdecl + _wcsset_s_l( + wchar_t *_Str, + size_t _SizeInChars, + unsigned int _Val, + _locale_t _Locale); + + _CRTIMP + errno_t + __cdecl + _wcsnset_s_l( + wchar_t *_Str, + size_t _SizeInChars, + unsigned int _Val, + size_t _Count, + _locale_t _Locale); + +#endif /* _WSTRING_S_DEFINED */ #ifndef _WTIME_S_DEFINED #define _WTIME_S_DEFINED - _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); - _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _wasctime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const struct tm *_Tm); + + _CRTIMP + errno_t + __cdecl + _wctime32_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time32_t *_Time); + + _CRTIMP + errno_t + __cdecl + _wstrdate_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_range_(>= , 9) size_t _SizeInWords); + + _CRTIMP + errno_t + __cdecl + _wstrtime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_ size_t _SizeInWords); + + _CRTIMP + errno_t + __cdecl + _wctime64_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time64_t *_Time); #if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL) #define _INC_WTIME_S_INL @@ -117,16 +666,46 @@ extern "C" { #ifndef _USE_32BIT_TIME_T __CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s(_Buffer,_SizeInWords,_Time); } #endif -#endif #endif - _CRTIMP errno_t __cdecl mbsrtowcs_s(size_t *_Retval,wchar_t *_Dst,size_t _SizeInWords,const char **_PSrc,size_t _N,mbstate_t *_State); - _CRTIMP errno_t __cdecl wcrtomb_s(size_t *_Retval,char *_Dst,size_t _SizeInBytes,wchar_t _Ch,mbstate_t *_State); - _CRTIMP errno_t __cdecl wcsrtombs_s(size_t *_Retval,char *_Dst,size_t _SizeInBytes,const wchar_t **_Src,size_t _Size,mbstate_t *_State); +#endif /* _WTIME_S_DEFINED */ + + _CRTIMP + errno_t + __cdecl + mbsrtowcs_s( + _Out_opt_ size_t *_Retval, + _Out_writes_opt_z_(_SizeInWords) wchar_t *_Dst, + _In_ size_t _SizeInWords, + _Inout_ _Deref_prepost_opt_valid_ const char **_PSrc, + _In_ size_t _N, + _Out_opt_ mbstate_t *_State); + + _CRTIMP + 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, + _Out_opt_ mbstate_t *_State); + + _CRTIMP + 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_ const wchar_t **_Src, + _In_ size_t _Size, + _Out_opt_ mbstate_t *_State); #ifdef __cplusplus } #endif -#endif -#endif +#endif /* MINGW_HAS_SECURE_API */ + +#endif /* _INC_WCHAR_S */ diff --git a/include/crt/time.h b/include/crt/time.h index b868ab9d8e9..d332eb4ba84 100644 --- a/include/crt/time.h +++ b/include/crt/time.h @@ -3,6 +3,7 @@ * This file is part of the w64 mingw-runtime package. * No warranty is given; refer to the file DISCLAIMER within this package. */ + #ifndef _TIME_H_ #define _TIME_H_ @@ -92,67 +93,295 @@ extern "C" { _CRTDATA(extern long _timezone); _CRTDATA(extern char * _tzname[2]); - _CRTIMP errno_t __cdecl _get_daylight(int *_Daylight); - _CRTIMP errno_t __cdecl _get_dstbias(long *_Daylight_savings_bias); - _CRTIMP errno_t __cdecl _get_timezone(long *_Timezone); - _CRTIMP errno_t __cdecl _get_tzname(size_t *_ReturnValue,char *_Buffer,size_t _SizeInBytes,int _Index); + _CRTIMP errno_t __cdecl _get_daylight(_Out_ int *_Daylight); + _CRTIMP errno_t __cdecl _get_dstbias(_Out_ long *_Daylight_savings_bias); + _CRTIMP errno_t __cdecl _get_timezone(_Out_ long *_Timezone); - _CRTIMP _CRT_INSECURE_DEPRECATE(asctime_s) char *__cdecl asctime(const struct tm *_Tm); - _CRTIMP _CRT_INSECURE_DEPRECATE(_ctime32_s) char *__cdecl _ctime32(const __time32_t *_Time); - _CRTIMP clock_t __cdecl clock(void); - _CRTIMP double __cdecl _difftime32(__time32_t _Time1,__time32_t _Time2); - _CRTIMP _CRT_INSECURE_DEPRECATE(_gmtime32_s) struct tm *__cdecl _gmtime32(const __time32_t *_Time); - _CRTIMP _CRT_INSECURE_DEPRECATE(_localtime32_s) struct tm *__cdecl _localtime32(const __time32_t *_Time); - _CRTIMP size_t __cdecl strftime(char *_Buf,size_t _SizeInBytes,const char *_Format,const struct tm *_Tm); - _CRTIMP size_t __cdecl _strftime_l(char *_Buf,size_t _Max_size,const char *_Format,const struct tm *_Tm,_locale_t _Locale); - _CRTIMP char *__cdecl _strdate(char *_Buffer); - _CRTIMP char *__cdecl _strtime(char *_Buffer); - _CRTIMP __time32_t __cdecl _time32(__time32_t *_Time); - _CRTIMP __time32_t __cdecl _mktime32(struct tm *_Tm); - _CRTIMP __time32_t __cdecl _mkgmtime32(struct tm *_Tm); + _CRTIMP + errno_t + __cdecl + _get_tzname( + _Out_ size_t *_ReturnValue, + _Out_writes_z_(_SizeInBytes) char *_Buffer, + _In_ size_t _SizeInBytes, + _In_ int _Index); + + _Check_return_ + _CRTIMP + _CRT_INSECURE_DEPRECATE(asctime_s) + char * + __cdecl + asctime( + _In_ const struct tm *_Tm); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_ctime32_s) + char * + __cdecl + _ctime32( + _In_ const __time32_t *_Time); + + _Check_return_ _CRTIMP clock_t __cdecl clock(void); + + _CRTIMP + double + __cdecl + _difftime32( + _In_ __time32_t _Time1, + _In_ __time32_t _Time2); + + _Check_return_ + _CRTIMP + _CRT_INSECURE_DEPRECATE(_gmtime32_s) + struct tm * + __cdecl + _gmtime32( + _In_ const __time32_t *_Time); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_localtime32_s) + struct tm * + __cdecl + _localtime32( + _In_ const __time32_t *_Time); + + _Success_(return > 0) + _CRTIMP + size_t + __cdecl + strftime( + _Out_writes_z_(_SizeInBytes) char *_Buf, + _In_ size_t _SizeInBytes, + _In_z_ _Printf_format_string_ const char *_Format, + _In_ const struct tm *_Tm); + + _Success_(return > 0) + _CRTIMP + size_t + __cdecl + _strftime_l( + _Out_writes_z_(_Max_size) char *_Buf, + _In_ size_t _Max_size, + _In_z_ _Printf_format_string_ const char *_Format, + _In_ const struct tm *_Tm, + _In_opt_ _locale_t _Locale); + + _CRTIMP char *__cdecl _strdate(_Out_writes_z_(9) char *_Buffer); + _CRTIMP char *__cdecl _strtime(_Out_writes_z_(9) char *_Buffer); + _CRTIMP __time32_t __cdecl _time32(_Out_opt_ __time32_t *_Time); + _CRTIMP __time32_t __cdecl _mktime32(_Inout_ struct tm *_Tm); + _CRTIMP __time32_t __cdecl _mkgmtime32(_Inout_ struct tm *_Tm); _CRTIMP void __cdecl _tzset(void); - _CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _getsystime(struct tm *_Tm); - _CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _setsystime(struct tm *_Tm,unsigned _MilliSec); + _CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _getsystime(_Out_ struct tm *_Tm); - _CRTIMP errno_t __cdecl asctime_s(char *_Buf,size_t _SizeInWords,const struct tm *_Tm); - _CRTIMP errno_t __cdecl _ctime32_s(char *_Buf,size_t _SizeInBytes,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _gmtime32_s(struct tm *_Tm,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _localtime32_s(struct tm *_Tm,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _strdate_s(char *_Buf,size_t _SizeInBytes); - _CRTIMP errno_t __cdecl _strtime_s(char *_Buf ,size_t _SizeInBytes); + _CRT_OBSOLETE(GetLocalTime) + unsigned + __cdecl + _setsystime( + _In_ struct tm *_Tm, + unsigned _MilliSec); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + asctime_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(26) char *_Buf, + _In_range_(>= , 26) size_t _SizeInBytes, + _In_ const struct tm *_Tm); + + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _ctime32_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(26) char *_Buf, + _In_ size_t _SizeInBytes, + _In_ const __time32_t *_Time); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _gmtime32_s( + _In_ struct tm *_Tm, + _In_ const __time32_t *_Time); + + _CRTIMP + errno_t + __cdecl + _localtime32_s( + _Out_ struct tm *_Tm, + _In_ const __time32_t *_Time); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _strdate_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf, + _In_range_(>= , 9) size_t _SizeInBytes); + + _Check_return_wat_ + _CRTIMP + errno_t + __cdecl + _strtime_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf, + _In_range_(>= , 9) size_t _SizeInBytes); #if _INTEGRAL_MAX_BITS >= 64 - _CRTIMP double __cdecl _difftime64(__time64_t _Time1,__time64_t _Time2); - _CRTIMP _CRT_INSECURE_DEPRECATE(_ctime64_s) char *__cdecl _ctime64(const __time64_t *_Time); - _CRTIMP _CRT_INSECURE_DEPRECATE(_gmtime64_s) struct tm *__cdecl _gmtime64(const __time64_t *_Time); - _CRTIMP _CRT_INSECURE_DEPRECATE(_localtime64_s) struct tm *__cdecl _localtime64(const __time64_t *_Time); - _CRTIMP __time64_t __cdecl _mktime64(struct tm *_Tm); - _CRTIMP __time64_t __cdecl _mkgmtime64(struct tm *_Tm); - _CRTIMP __time64_t __cdecl _time64(__time64_t *_Time); - _CRTIMP errno_t __cdecl _ctime64_s(char *_Buf,size_t _SizeInBytes,const __time64_t *_Time); - _CRTIMP errno_t __cdecl _gmtime64_s(struct tm *_Tm,const __time64_t *_Time); - _CRTIMP errno_t __cdecl _localtime64_s(struct tm *_Tm,const __time64_t *_Time); -#endif + _Check_return_ + _CRTIMP + double + __cdecl + _difftime64( + _In_ __time64_t _Time1, + _In_ __time64_t _Time2); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_ctime64_s) + char * + __cdecl + _ctime64( + _In_ const __time64_t *_Time); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_gmtime64_s) + struct tm * + __cdecl + _gmtime64( + _In_ const __time64_t *_Time); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_localtime64_s) + struct tm * + __cdecl + _localtime64( + _In_ const __time64_t *_Time); + + _CRTIMP __time64_t __cdecl _mktime64(_Inout_ struct tm *_Tm); + _CRTIMP __time64_t __cdecl _mkgmtime64(_Inout_ struct tm *_Tm); + _CRTIMP __time64_t __cdecl _time64(_Out_opt_ __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _ctime64_s( + _Out_writes_z_(_SizeInBytes) char *_Buf, + _In_ size_t _SizeInBytes, + _In_ const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _gmtime64_s( + _Out_ struct tm *_Tm, + _In_ const __time64_t *_Time); + + _CRTIMP + errno_t + __cdecl + _localtime64_s( + _Out_ struct tm *_Tm, + _In_ const __time64_t *_Time); + +#endif /* _INTEGRAL_MAX_BITS >= 64 */ #ifndef _WTIME_DEFINED #define _WTIME_DEFINED - _CRTIMP _CRT_INSECURE_DEPRECATE(_wasctime_s) wchar_t *__cdecl _wasctime(const struct tm *_Tm); - _CRTIMP wchar_t *__cdecl _wctime(const time_t *_Time); - _CRTIMP _CRT_INSECURE_DEPRECATE(_wctime32_s) wchar_t *__cdecl _wctime32(const __time32_t *_Time); - _CRTIMP size_t __cdecl wcsftime(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm); - _CRTIMP size_t __cdecl _wcsftime_l(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm,_locale_t _Locale); - _CRTIMP wchar_t *__cdecl _wstrdate(wchar_t *_Buffer); - _CRTIMP wchar_t *__cdecl _wstrtime(wchar_t *_Buffer); - _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); - _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); + _CRTIMP + _CRT_INSECURE_DEPRECATE(_wasctime_s) + wchar_t * + __cdecl + _wasctime( + _In_ const struct tm *_Tm); + + _CRTIMP wchar_t *__cdecl _wctime(const time_t *_Time); + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_wctime32_s) + wchar_t * + __cdecl + _wctime32( + _In_ const __time32_t *_Time); + + _Success_(return > 0) + _CRTIMP + size_t + __cdecl + wcsftime( + _Out_writes_z_(_SizeInWords) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_ const struct tm *_Tm); + + _Success_(return > 0) + _CRTIMP + size_t + __cdecl + _wcsftime_l( + _Out_writes_z_(_SizeInWords) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_z_ _Printf_format_string_ const wchar_t *_Format, + _In_ const struct tm *_Tm, + _In_opt_ _locale_t _Locale); + + _CRTIMP wchar_t *__cdecl _wstrdate(_Out_writes_z_(9) wchar_t *_Buffer); + _CRTIMP wchar_t *__cdecl _wstrtime(_Out_writes_z_(9) wchar_t *_Buffer); + + _CRTIMP + errno_t + __cdecl + _wasctime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_range_(>= , 26) size_t _SizeInWords, + _In_ const struct tm *_Tm); + + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _wctime32_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time32_t *_Time); + + _CRTIMP + errno_t + __cdecl + _wstrdate_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_ size_t _SizeInWords); + + _CRTIMP + errno_t + __cdecl + _wstrtime_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf, + _In_range_(>= , 9) size_t _SizeInWords); + #if _INTEGRAL_MAX_BITS >= 64 - _CRTIMP _CRT_INSECURE_DEPRECATE(_wctime64_s) wchar_t *__cdecl _wctime64(const __time64_t *_Time); - _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); -#endif + + _CRTIMP + _CRT_INSECURE_DEPRECATE(_wctime64_s) + wchar_t * + __cdecl + _wctime64( + _In_ const __time64_t *_Time); + + _Success_(return == 0) + _CRTIMP + errno_t + __cdecl + _wctime64_s( + _Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf, + _In_ size_t _SizeInWords, + _In_ const __time64_t *_Time); + +#endif /* _INTEGRAL_MAX_BITS >= 64 */ #if !defined (RC_INVOKED) && !defined (_INC_WTIME_INL) #define _INC_WTIME_INL @@ -218,4 +447,3 @@ __CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time64(_Time); } #pragma pack(pop) #endif /* End _TIME_H_ */ - diff --git a/include/ndk/iotypes.h b/include/ndk/iotypes.h index 32e634946bc..0cc4e6dab34 100644 --- a/include/ndk/iotypes.h +++ b/include/ndk/iotypes.h @@ -174,7 +174,7 @@ extern POBJECT_TYPE NTSYSAPI IoDriverObjectType; #define DNF_LEGACY_DRIVER 0x00004000 #define DNF_STOPPED 0x00008000 #define DNF_WILL_BE_REMOVED 0x00010000 -#define DNF_NEED_TO_ENUM 0x00020000 +#define DNF_LEGACY_RESOURCE_DEVICENODE 0x00020000 #define DNF_NOT_CONFIGURED 0x00040000 #define DNF_REINSTALL 0x00080000 #define DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x00100000 // ??? diff --git a/include/ndk/pstypes.h b/include/ndk/pstypes.h index 86fc1b05f94..caeb127e080 100644 --- a/include/ndk/pstypes.h +++ b/include/ndk/pstypes.h @@ -89,11 +89,17 @@ extern POBJECT_TYPE NTSYSAPI PsJobType; // // Flags for NtCreateProcessEx // -#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001 -#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002 -#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004 +#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001 +#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002 +#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004 #define PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00000008 -#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010 +#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010 +#define PROCESS_CREATE_FLAGS_ALL_LARGE_PAGE_FLAGS PROCESS_CREATE_FLAGS_LARGE_PAGES +#define PROCESS_CREATE_FLAGS_LEGAL_MASK (PROCESS_CREATE_FLAGS_BREAKAWAY | \ + PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT | \ + PROCESS_CREATE_FLAGS_INHERIT_HANDLES | \ + PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE | \ + PROCESS_CREATE_FLAGS_ALL_LARGE_PAGE_FLAGS) // // Process priority classes @@ -106,18 +112,6 @@ extern POBJECT_TYPE NTSYSAPI PsJobType; #define PROCESS_PRIORITY_CLASS_BELOW_NORMAL 5 #define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL 6 -// -// NtCreateProcessEx flags -// -#define PS_REQUEST_BREAKAWAY 1 -#define PS_NO_DEBUG_INHERIT 2 -#define PS_INHERIT_HANDLES 4 -#define PS_LARGE_PAGES 8 -#define PS_ALL_FLAGS (PS_REQUEST_BREAKAWAY | \ - PS_NO_DEBUG_INHERIT | \ - PS_INHERIT_HANDLES | \ - PS_LARGE_PAGES) - // // Process base priorities // diff --git a/include/psdk/wincrypt.h b/include/psdk/wincrypt.h index d6850a75d99..e66b3770da4 100644 --- a/include/psdk/wincrypt.h +++ b/include/psdk/wincrypt.h @@ -1096,20 +1096,33 @@ typedef struct _CERT_SYSTEM_STORE_RELOCATE_PARA { } DUMMYUNIONNAME2; } CERT_SYSTEM_STORE_RELOCATE_PARA, *PCERT_SYSTEM_STORE_RELOCATE_PARA; -typedef BOOL (WINAPI *PFN_CERT_ENUM_SYSTEM_STORE_LOCATION)( - LPCWSTR pwszStoreLocation, DWORD dwFlags, void *pvReserved, void *pvArg); +typedef BOOL +(WINAPI *PFN_CERT_ENUM_SYSTEM_STORE_LOCATION)( + _In_ LPCWSTR pwszStoreLocation, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved, + _Inout_opt_ void *pvArg); -typedef BOOL (WINAPI *PFN_CERT_ENUM_SYSTEM_STORE)(const void *pvSystemStore, - DWORD dwFlags, PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved, - void *pvArg); +typedef BOOL +(WINAPI *PFN_CERT_ENUM_SYSTEM_STORE)( + _In_ const void *pvSystemStore, + _In_ DWORD dwFlags, + _In_ PCERT_SYSTEM_STORE_INFO pStoreInfo, + _Reserved_ void *pvReserved, + _Inout_opt_ void *pvArg); -typedef BOOL (WINAPI *PFN_CERT_ENUM_PHYSICAL_STORE)(const void *pvSystemStore, - DWORD dwFlags, LPCWSTR pwszStoreName, PCERT_PHYSICAL_STORE_INFO pStoreInfo, - void *pvReserved, void *pvArg); +typedef BOOL +(WINAPI *PFN_CERT_ENUM_PHYSICAL_STORE)( + _In_ const void *pvSystemStore, + _In_ DWORD dwFlags, + _In_ LPCWSTR pwszStoreName, + _In_ PCERT_PHYSICAL_STORE_INFO pStoreInfo, + _Reserved_ void *pvReserved, + _Inout_opt_ void *pvArg); /* Encode/decode object */ -typedef LPVOID (__WINE_ALLOC_SIZE(1) WINAPI *PFN_CRYPT_ALLOC)(size_t cbsize); -typedef VOID (WINAPI *PFN_CRYPT_FREE)(LPVOID pv); +typedef LPVOID (__WINE_ALLOC_SIZE(1) WINAPI *PFN_CRYPT_ALLOC)(_In_ size_t cbsize); +typedef VOID(WINAPI *PFN_CRYPT_FREE)(_In_ LPVOID pv); typedef struct _CRYPT_ENCODE_PARA { DWORD cbSize; @@ -1132,58 +1145,114 @@ typedef struct _CERT_STORE_PROV_INFO { HCRYPTOIDFUNCADDR hStoreProvFuncAddr2; } CERT_STORE_PROV_INFO, *PCERT_STORE_PROV_INFO; -typedef BOOL (WINAPI *PFN_CERT_DLL_OPEN_STORE_PROV_FUNC)( - LPCSTR lpszStoreProvider, DWORD dwEncodingType, HCRYPTPROV_LEGACY hCryptProv, - DWORD dwFlags, const void *pvPara, HCERTSTORE hCertStore, - PCERT_STORE_PROV_INFO pStoreProvInfo); +typedef BOOL +(WINAPI *PFN_CERT_DLL_OPEN_STORE_PROV_FUNC)( + _In_ LPCSTR lpszStoreProvider, + _In_ DWORD dwEncodingType, + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwFlags, + _In_opt_ const void *pvPara, + _In_ HCERTSTORE hCertStore, + _Inout_ PCERT_STORE_PROV_INFO pStoreProvInfo); -typedef void (WINAPI *PFN_CERT_STORE_PROV_CLOSE)(HCERTSTOREPROV hStoreProv, - DWORD dwFlags); +typedef void +(WINAPI *PFN_CERT_STORE_PROV_CLOSE)( + _Inout_opt_ HCERTSTOREPROV hStoreProv, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_READ_CERT)(HCERTSTOREPROV hStoreProv, - PCCERT_CONTEXT pStoreCertContext, DWORD dwFlags, - PCCERT_CONTEXT *ppProvCertContext); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_READ_CERT)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pStoreCertContext, + _In_ DWORD dwFlags, + _Outptr_ PCCERT_CONTEXT *ppProvCertContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_WRITE_CERT)(HCERTSTOREPROV hStoreProv, - PCCERT_CONTEXT pCertContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_WRITE_CERT)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_DELETE_CERT)( - HCERTSTOREPROV hStoreProv, PCCERT_CONTEXT pCertContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_DELETE_CERT)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_SET_CERT_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCERT_CONTEXT pCertContext, DWORD dwPropId, - DWORD dwFlags, const void *pvData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_SET_CERT_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_READ_CRL)(HCERTSTOREPROV hStoreProv, - PCCRL_CONTEXT pStoreCrlContext, DWORD dwFlags, - PCCRL_CONTEXT *ppProvCrlContext); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_READ_CRL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pStoreCrlContext, + _In_ DWORD dwFlags, + _Outptr_ PCCRL_CONTEXT *ppProvCrlContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_WRITE_CRL)(HCERTSTOREPROV hStoreProv, - PCCRL_CONTEXT pCrlContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_WRITE_CRL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_DELETE_CRL)(HCERTSTOREPROV hStoreProv, - PCCRL_CONTEXT pCrlContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_DELETE_CRL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_SET_CRL_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCRL_CONTEXT pCrlContext, DWORD dwPropId, - DWORD dwFlags, const void *pvData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_SET_CRL_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_READ_CTL)(HCERTSTOREPROV hStoreProv, - PCCTL_CONTEXT pStoreCtlContext, DWORD dwFlags, - PCCTL_CONTEXT *ppProvCtlContext); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_READ_CTL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCTL_CONTEXT pStoreCtlContext, + _In_ DWORD dwFlags, + _Outptr_ PCCTL_CONTEXT *ppProvCtlContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_WRITE_CTL)(HCERTSTOREPROV hStoreProv, - PCCTL_CONTEXT pCtlContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_WRITE_CTL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_DELETE_CTL)( - HCERTSTOREPROV hStoreProv, PCCTL_CONTEXT pCtlContext, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_DELETE_CTL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_SET_CTL_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCTL_CONTEXT pCtlContext, DWORD dwPropId, - DWORD dwFlags, const void *pvData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_SET_CTL_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_CONTROL)(HCERTSTOREPROV hStoreProv, - DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_CONTROL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ DWORD dwFlags, + _In_ DWORD dwCtrlType, + _In_opt_ void const *pvCtrlPara); typedef struct _CERT_STORE_PROV_FIND_INFO { DWORD cbSize; @@ -1195,36 +1264,79 @@ typedef struct _CERT_STORE_PROV_FIND_INFO { typedef const CERT_STORE_PROV_FIND_INFO CCERT_STORE_PROV_FIND_INFO, *PCCERT_STORE_PROV_FIND_INFO; -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FIND_CERT)(HCERTSTOREPROV hStoreProv, - PCCERT_STORE_PROV_FIND_INFO pFindInfo, PCCERT_CONTEXT pPrevCertContext, - DWORD dwFlags, void **ppvStoreProvFindInfo, PCCERT_CONTEXT *ppProvCertContext); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_FIND_CERT)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_STORE_PROV_FIND_INFO pFindInfo, + _In_ PCCERT_CONTEXT pPrevCertContext, + _In_ DWORD dwFlags, + _Inout_ void **ppvStoreProvFindInfo, + _Outptr_ PCCERT_CONTEXT *ppProvCertContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FREE_FIND_CERT)( - HCERTSTOREPROV hStoreProv, PCCERT_CONTEXT pCertContext, - void *pvStoreProvFindInfo, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_FREE_FIND_CERT)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pCertContext, + _In_ void *pvStoreProvFindInfo, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_GET_CERT_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCERT_CONTEXT pCertContext, DWORD dwPropId, - DWORD dwFlags, void *pvData, DWORD *pcbData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_GET_CERT_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FIND_CRL)(HCERTSTOREPROV hStoreProv, - PCCERT_STORE_PROV_FIND_INFO pFindInfo, PCCRL_CONTEXT pPrevCrlContext, - DWORD dwFlags, void **ppvStoreProvFindInfo, PCCRL_CONTEXT *ppProvCrlContext); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_FIND_CRL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_STORE_PROV_FIND_INFO pFindInfo, + _In_ PCCRL_CONTEXT pPrevCrlContext, + _In_ DWORD dwFlags, + _Inout_ void **ppvStoreProvFindInfo, + _Outptr_ PCCRL_CONTEXT *ppProvCrlContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FREE_FIND_CRL)( - HCERTSTOREPROV hStoreProv, PCCRL_CONTEXT pCrlContext, - void *pvStoreProvFindInfo, DWORD dwFlags); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_FREE_FIND_CRL)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ void *pvStoreProvFindInfo, + _In_ DWORD dwFlags); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_GET_CRL_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCRL_CONTEXT pCrlContext, DWORD dwPropId, - DWORD dwFlags, void *pvData, DWORD *pcbData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_GET_CRL_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FIND_CTL)(HCERTSTOREPROV hStoreProv, - PCCTL_CONTEXT pCtlContext, void *pvStoreProvFindInfo, DWORD dwFlags); +typedef +_Success_(return != 0) +BOOL +(WINAPI *PFN_CERT_STORE_PROV_FIND_CTL)( + _In_ HCERTSTOREPROV hStoreProv, + _In_ PCCERT_STORE_PROV_FIND_INFO pFindInfo, + _In_ PCCTL_CONTEXT pPrevCtlContext, + _In_ DWORD dwFlags, + _Inout_ void **ppvStoreProvFindInfo, + _Outptr_ PCCTL_CONTEXT *ppProvCtlContext); -typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_GET_CTL_PROPERTY)( - HCERTSTOREPROV hStoreProv, PCCTL_CONTEXT pCtlContext, DWORD dwPropId, - DWORD dwFlags, void *pvData); +typedef BOOL +(WINAPI *PFN_CERT_STORE_PROV_GET_CTL_PROPERTY)( + _Inout_ HCERTSTOREPROV hStoreProv, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); typedef struct _CERT_CREATE_CONTEXT_PARA { DWORD cbSize; @@ -1237,10 +1349,17 @@ typedef struct _CRYPT_OID_FUNC_ENTRY { void *pvFuncAddr; } CRYPT_OID_FUNC_ENTRY, *PCRYPT_OID_FUNC_ENTRY; -typedef BOOL (WINAPI *PFN_CRYPT_ENUM_OID_FUNC)(DWORD dwEncodingType, - LPCSTR pszFuncName, LPCSTR pszOID, DWORD cValue, const DWORD rgdwValueType[], - LPCWSTR const rgpwszValueName[], const BYTE * const rgpbValueData[], - const DWORD rgcbValueData[], void *pvArg); +typedef BOOL +(WINAPI *PFN_CRYPT_ENUM_OID_FUNC)( + _In_ DWORD dwEncodingType, + _In_ LPCSTR pszFuncName, + _In_ LPCSTR pszOID, + _In_ DWORD cValue, + _In_reads_(cValue) const DWORD rgdwValueType[], + _In_reads_(cValue) LPCWSTR const rgpwszValueName[], + _In_reads_(cValue) const BYTE * const rgpbValueData[], + _In_reads_(cValue) const DWORD rgcbValueData[], + _Inout_opt_ void *pvArg); #define CRYPT_MATCH_ANY_ENCODING_TYPE 0xffffffff @@ -1258,8 +1377,10 @@ typedef struct _CRYPT_OID_INFO { } CRYPT_OID_INFO, *PCRYPT_OID_INFO; typedef const CRYPT_OID_INFO CCRYPT_OID_INFO, *PCCRYPT_OID_INFO; -typedef BOOL (WINAPI *PFN_CRYPT_ENUM_OID_INFO)(PCCRYPT_OID_INFO pInfo, - void *pvArg); +typedef BOOL +(WINAPI *PFN_CRYPT_ENUM_OID_INFO)( + _In_ PCCRYPT_OID_INFO pInfo, + _Inout_opt_ void *pvArg); typedef struct _CRYPT_SIGN_MESSAGE_PARA { DWORD cbSize; @@ -1288,8 +1409,12 @@ typedef struct _CRYPT_SIGN_MESSAGE_PARA { #define CRYPT_MESSAGE_KEYID_SIGNER_FLAG 0x00000004 #define CRYPT_MESSAGE_SILENT_KEYSET_FLAG 0x00000008 -typedef PCCERT_CONTEXT (WINAPI *PFN_CRYPT_GET_SIGNER_CERTIFICATE)(void *pvArg, - DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hMsgCertStore); +typedef PCCERT_CONTEXT +(WINAPI *PFN_CRYPT_GET_SIGNER_CERTIFICATE)( + _Inout_opt_ void *pvGetArg, + _In_ DWORD dwCertEncodingType, + _In_ PCERT_INFO pSignerId, + _In_ HCERTSTORE hMsgCertStore); typedef struct _CRYPT_VERIFY_MESSAGE_PARA { DWORD cbSize; @@ -1373,24 +1498,30 @@ typedef struct _CRYPT_URL_INFO { typedef HANDLE HCRYPTASYNC, *PHCRYPTASYNC; -typedef void (WINAPI *PFN_CRYPT_ASYNC_PARAM_FREE_FUNC)(LPSTR pszParamOid, - LPVOID pvParam); +typedef void +(WINAPI *PFN_CRYPT_ASYNC_PARAM_FREE_FUNC)( + _In_ LPSTR pszParamOid, + _In_ LPVOID pvParam); #define CRYPT_PARAM_ASYNC_RETRIEVAL_COMPLETION ((LPCSTR)1) #define CRYPT_PARAM_CANCEL_ASYNC_RETRIEVAL ((LPCSTR)2) -typedef void (WINAPI *PFN_CRYPT_ASYNC_RETRIEVAL_COMPLETION_FUNC)( - void *pvCompletion, DWORD dwCompletionCode, LPCSTR pszURL, LPSTR pszObjectOid, - void *pvObject); +typedef void +(WINAPI *PFN_CRYPT_ASYNC_RETRIEVAL_COMPLETION_FUNC)( + _Inout_opt_ void *pvCompletion, + _In_ DWORD dwCompletionCode, + _In_ LPCSTR pszURL, + _In_opt_ LPSTR pszObjectOid, + _In_ void *pvObject); -typedef struct _CRYPT_ASYNC_RETRIEVAL_COMPLETION -{ - PFN_CRYPT_ASYNC_RETRIEVAL_COMPLETION_FUNC pfnCompletion; - void *pvCompletion; +typedef struct _CRYPT_ASYNC_RETRIEVAL_COMPLETION { + __callback PFN_CRYPT_ASYNC_RETRIEVAL_COMPLETION_FUNC pfnCompletion; + _Inout_opt_ void *pvCompletion; } CRYPT_ASYNC_RETRIEVAL_COMPLETION, *PCRYPT_ASYNC_RETRIEVAL_COMPLETION; -typedef BOOL (WINAPI *PFN_CANCEL_ASYNC_RETRIEVAL_FUNC)( - HCRYPTASYNC hAsyncRetrieve); +typedef BOOL +(WINAPI *PFN_CANCEL_ASYNC_RETRIEVAL_FUNC)( + _In_opt_ HCRYPTASYNC hAsyncRetrieve); typedef struct _CRYPT_BLOB_ARRAY { @@ -1429,8 +1560,11 @@ typedef struct _CRYPT_RETRIEVE_AUX_INFO { DWORD dwMaxUrlRetrievalByteCount; } CRYPT_RETRIEVE_AUX_INFO, *PCRYPT_RETRIEVE_AUX_INFO; -typedef void (WINAPI *PFN_FREE_ENCODED_OBJECT_FUNC)(LPCSTR pszObjectOid, - PCRYPT_BLOB_ARRAY pObject, void *pvFreeContext); +typedef void +(WINAPI *PFN_FREE_ENCODED_OBJECT_FUNC)( + _In_opt_ LPCSTR pszObjectOid, + _Inout_ PCRYPT_BLOB_ARRAY pObject, + _Inout_opt_ void *pvFreeContext); #define SCHEME_OID_RETRIEVE_ENCODED_OBJECT_FUNC \ "SchemeDllRetrieveEncodedObject" @@ -1478,7 +1612,10 @@ BOOL WINAPI ContextDllCreateObjectContext(LPCSTR pszObjectOid, #define CRYPT_CHECK_FRESHNESS_TIME_VALIDITY 0x00000400 #define CRYPT_ACCUMULATIVE_TIMEOUT 0x00000800 -typedef BOOL (WINAPI *PFN_CRYPT_CANCEL_RETRIEVAL)(DWORD dwFlags, void *pvArg); +typedef BOOL +(WINAPI *PFN_CRYPT_CANCEL_RETRIEVAL)( + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg); typedef struct _CERT_CRL_CONTEXT_PAIR { @@ -3405,8 +3542,12 @@ typedef struct _CERT_CHAIN_ENGINE_CONFIG /* message-related definitions */ -typedef BOOL (WINAPI *PFN_CMSG_STREAM_OUTPUT)(const void *pvArg, BYTE *pbData, - DWORD cbData, BOOL fFinal); +typedef BOOL +(WINAPI *PFN_CMSG_STREAM_OUTPUT)( + _In_opt_ const void *pvArg, + _In_reads_bytes_opt_(cbData) BYTE *pbData, + _In_ DWORD cbData, + _In_ BOOL fFinal); #define CMSG_INDEFINITE_LENGTH 0xffffffff @@ -3808,8 +3949,8 @@ typedef struct _CMSG_CMS_RECIPIENT_INFO { #define CMSG_KEY_AGREE_VERSION CMSG_ENVELOPED_RECIPIENT_V3 #define CMSG_MAIL_LIST_VERSION CMSG_ENVELOPED_RECIPIENT_V4 -typedef void * (WINAPI *PFN_CMSG_ALLOC)(size_t cb); -typedef void (WINAPI *PFN_CMSG_FREE)(void *pv); +typedef void * (WINAPI *PFN_CMSG_ALLOC)(_In_ size_t cb); +typedef void (WINAPI *PFN_CMSG_FREE)(_Inout_ void *pv); typedef struct _CMSG_CONTENT_ENCRYPT_INFO { DWORD cbSize; @@ -3841,20 +3982,27 @@ typedef struct _CMSG_CTRL_KEY_TRANS_DECRYPT_PARA { DWORD dwRecipientIndex; } CMSG_CTRL_KEY_TRANS_DECRYPT_PARA, *PCMSG_CTRL_KEY_TRANS_DECRYPT_PARA; -typedef BOOL (WINAPI *PFN_CMSG_GEN_CONTENT_ENCRYPT_KEY)( - PCMSG_CONTENT_ENCRYPT_INFO pContentEncryptInfo, DWORD dwFlags, - void *pvReserved); +typedef BOOL +(WINAPI *PFN_CMSG_GEN_CONTENT_ENCRYPT_KEY)( + _Inout_ PCMSG_CONTENT_ENCRYPT_INFO pContentEncryptInfo, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); -typedef BOOL (WINAPI *PFN_CMSG_EXPORT_KEY_TRANS)( - PCMSG_CONTENT_ENCRYPT_INFO pContentEncryptInfo, - PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO pKeyTransEncodeInfo, - PCMSG_KEY_TRANS_ENCRYPT_INFO pKeyTransEncryptInfo, - DWORD dwFlags, void *pvReserved); +typedef BOOL +(WINAPI *PFN_CMSG_EXPORT_KEY_TRANS)( + _In_ PCMSG_CONTENT_ENCRYPT_INFO pContentEncryptInfo, + _In_ PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO pKeyTransEncodeInfo, + _Inout_ PCMSG_KEY_TRANS_ENCRYPT_INFO pKeyTransEncryptInfo, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); -typedef BOOL (WINAPI *PFN_CMSG_IMPORT_KEY_TRANS)( - PCRYPT_ALGORITHM_IDENTIFIER pContentEncryptionAlgorithm, - PCMSG_CTRL_KEY_TRANS_DECRYPT_PARA pKeyTransDecryptPara, DWORD dwFlags, - void *pvReserved, HCRYPTKEY *phContentEncryptKey); +typedef BOOL +(WINAPI *PFN_CMSG_IMPORT_KEY_TRANS)( + _In_ PCRYPT_ALGORITHM_IDENTIFIER pContentEncryptionAlgorithm, + _In_ PCMSG_CTRL_KEY_TRANS_DECRYPT_PARA pKeyTransDecryptPara, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved, + _Out_ HCRYPTKEY *phContentEncryptKey); /* CryptMsgGetAndVerifySigner flags */ #define CMSG_TRUSTED_SIGNER_FLAG 0x1 @@ -3879,489 +4027,1476 @@ typedef BOOL (WINAPI *PFN_CMSG_IMPORT_KEY_TRANS)( /* function declarations */ /* advapi32.dll */ -WINADVAPI BOOL WINAPI CryptAcquireContextA(HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD); -WINADVAPI BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD); -#define CryptAcquireContext WINELIB_NAME_AW(CryptAcquireContext) -WINADVAPI BOOL WINAPI CryptGenRandom (HCRYPTPROV, DWORD, BYTE *); -WINADVAPI BOOL WINAPI CryptContextAddRef (HCRYPTPROV, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptCreateHash (HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH *); -WINADVAPI BOOL WINAPI CryptDecrypt (HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE *, DWORD *); -WINADVAPI BOOL WINAPI CryptDeriveKey (HCRYPTPROV, ALG_ID, HCRYPTHASH, DWORD, HCRYPTKEY *); -WINADVAPI BOOL WINAPI CryptDestroyHash (HCRYPTHASH); -WINADVAPI BOOL WINAPI CryptDestroyKey (HCRYPTKEY); -WINADVAPI BOOL WINAPI CryptDuplicateKey (HCRYPTKEY, DWORD *, DWORD, HCRYPTKEY *); -WINADVAPI BOOL WINAPI CryptDuplicateHash (HCRYPTHASH, DWORD *, DWORD, HCRYPTHASH *); -WINADVAPI BOOL WINAPI CryptEncrypt (HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE *, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptEnumProvidersA (DWORD, DWORD *, DWORD, DWORD *, LPSTR, DWORD *); -WINADVAPI BOOL WINAPI CryptEnumProvidersW (DWORD, DWORD *, DWORD, DWORD *, LPWSTR, DWORD *); -#define CryptEnumProviders WINELIB_NAME_AW(CryptEnumProviders) -WINADVAPI BOOL WINAPI CryptEnumProviderTypesA (DWORD, DWORD *, DWORD, DWORD *, LPSTR, DWORD *); -WINADVAPI BOOL WINAPI CryptEnumProviderTypesW (DWORD, DWORD *, DWORD, DWORD *, LPWSTR, DWORD *); -#define CryptEnumProviderTypes WINELIB_NAME_AW(CryptEnumProviderTypes) -WINADVAPI BOOL WINAPI CryptExportKey (HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, BYTE *, DWORD *); -WINADVAPI BOOL WINAPI CryptGenKey (HCRYPTPROV, ALG_ID, DWORD, HCRYPTKEY *); -WINADVAPI BOOL WINAPI CryptGetKeyParam (HCRYPTKEY, DWORD, BYTE *, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptGetHashParam (HCRYPTHASH, DWORD, BYTE *, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptGetProvParam (HCRYPTPROV, DWORD, BYTE *, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptGetDefaultProviderA (DWORD, DWORD *, DWORD, LPSTR, DWORD *); -WINADVAPI BOOL WINAPI CryptGetDefaultProviderW (DWORD, DWORD *, DWORD, LPWSTR, DWORD *); -#define CryptGetDefaultProvider WINELIB_NAME_AW(CryptGetDefaultProvider) -WINADVAPI BOOL WINAPI CryptGetUserKey (HCRYPTPROV, DWORD, HCRYPTKEY *); -WINADVAPI BOOL WINAPI CryptHashData (HCRYPTHASH, CONST BYTE *, DWORD, DWORD); -WINADVAPI BOOL WINAPI CryptHashSessionKey (HCRYPTHASH, HCRYPTKEY, DWORD); -WINADVAPI BOOL WINAPI CryptImportKey (HCRYPTPROV, CONST BYTE *, DWORD, HCRYPTKEY, DWORD, HCRYPTKEY *); +WINADVAPI +BOOL +WINAPI +CryptAcquireContextA( + _Out_ HCRYPTPROV *, + _In_opt_ LPCSTR, + _In_opt_ LPCSTR, + _In_ DWORD, + _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptAcquireContextW( + _Out_ HCRYPTPROV *, + _In_opt_ LPCWSTR, + _In_opt_ LPCWSTR, + _In_ DWORD, + _In_ DWORD); + +#define CryptAcquireContext WINELIB_NAME_AW(CryptAcquireContext) + +WINADVAPI +BOOL +WINAPI +CryptGenRandom( + _In_ HCRYPTPROV hProv, + _In_ DWORD dwLen, + _Inout_updates_bytes_(dwLen) BYTE *pbBuffer); + +WINADVAPI +BOOL +WINAPI +CryptContextAddRef( + _In_ HCRYPTPROV, + _Reserved_ DWORD *, + _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptCreateHash( + _In_ HCRYPTPROV, + _In_ ALG_ID, + _In_ HCRYPTKEY, + _In_ DWORD, + _Out_ HCRYPTHASH *); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptDecrypt( + _In_ HCRYPTKEY hKey, + _In_ HCRYPTHASH hHash, + _In_ BOOL Final, + _In_ DWORD dwFlags, + _Inout_updates_bytes_to_(*pdwDataLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen); + +WINADVAPI +BOOL +WINAPI +CryptDeriveKey( + _In_ HCRYPTPROV, + _In_ ALG_ID, + _In_ HCRYPTHASH, + _In_ DWORD, + _Out_ HCRYPTKEY *); + +WINADVAPI BOOL WINAPI CryptDestroyHash(_In_ HCRYPTHASH); +WINADVAPI BOOL WINAPI CryptDestroyKey(_In_ HCRYPTKEY); + +WINADVAPI +BOOL +WINAPI +CryptDuplicateKey( + _In_ HCRYPTKEY, + _Reserved_ DWORD *, + _In_ DWORD, + _Out_ HCRYPTKEY *); + +WINADVAPI +BOOL +WINAPI +CryptDuplicateHash( + _In_ HCRYPTHASH, + _Reserved_ DWORD *, + _In_ DWORD, + _Out_ HCRYPTHASH *); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptEncrypt( + _In_ HCRYPTKEY hKey, + _In_ HCRYPTHASH hHash, + _In_ BOOL Final, + _In_ DWORD dwFlags, + _Inout_updates_bytes_to_opt_(dwBufLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen, + _In_ DWORD dwBufLen); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptEnumProvidersA( + _In_ DWORD dwIndex, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_ DWORD *pdwProvType, + _Out_writes_bytes_to_opt_(*pcbProvName, *pcbProvName) LPSTR szProvName, + _Inout_ DWORD *pcbProvName); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptEnumProvidersW( + _In_ DWORD dwIndex, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_ DWORD *pdwProvType, + _Out_writes_bytes_to_opt_(*pcbProvName, *pcbProvName) LPWSTR szProvName, + _Inout_ DWORD *pcbProvName); + +#define CryptEnumProviders WINELIB_NAME_AW(CryptEnumProviders) + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptEnumProviderTypesA( + _In_ DWORD dwIndex, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_ DWORD *pdwProvType, + _Out_writes_bytes_to_opt_(*pcbTypeName, *pcbTypeName) LPSTR szTypeName, + _Inout_ DWORD *pcbTypeName); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptEnumProviderTypesW( + _In_ DWORD dwIndex, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_ DWORD *pdwProvType, + _Out_writes_bytes_to_opt_(*pcbTypeName, *pcbTypeName) LPWSTR szTypeName, + _Inout_ DWORD *pcbTypeName); + +#define CryptEnumProviderTypes WINELIB_NAME_AW(CryptEnumProviderTypes) + +WINADVAPI +BOOL +WINAPI +CryptExportKey( + _In_ HCRYPTKEY hKey, + _In_ HCRYPTKEY hExpKey, + _In_ DWORD dwBlobType, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pdwDataLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen); + +WINADVAPI +BOOL +WINAPI +CryptGenKey( + _In_ HCRYPTPROV, + _In_ ALG_ID, + _In_ DWORD, + _Out_ HCRYPTKEY *); + +WINADVAPI +BOOL +WINAPI +CryptGetKeyParam( + _In_ HCRYPTKEY hKey, + _In_ DWORD dwParam, + _Out_writes_bytes_to_opt_(*pdwDataLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen, + _In_ DWORD dwFlags); + +WINADVAPI +BOOL +WINAPI +CryptGetHashParam( + _In_ HCRYPTHASH hHash, + _In_ DWORD dwParam, + _Out_writes_bytes_to_opt_(*pdwDataLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen, + _In_ DWORD dwFlags); + +WINADVAPI +BOOL +WINAPI +CryptGetProvParam( + _In_ HCRYPTPROV hProv, + _In_ DWORD dwParam, + _Out_writes_bytes_to_opt_(*pdwDataLen, *pdwDataLen) BYTE *pbData, + _Inout_ DWORD *pdwDataLen, + _In_ DWORD dwFlags); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptGetDefaultProviderA( + _In_ DWORD dwProvType, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbProvName, *pcbProvName) LPSTR pszProvName, + _Inout_ DWORD *pcbProvName); + +_Success_(return != 0) +WINADVAPI +BOOL +WINAPI +CryptGetDefaultProviderW( + _In_ DWORD dwProvType, + _Reserved_ DWORD *pdwReserved, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbProvName, *pcbProvName) LPWSTR pszProvName, + _Inout_ DWORD *pcbProvName); + +#define CryptGetDefaultProvider WINELIB_NAME_AW(CryptGetDefaultProvider) + +WINADVAPI BOOL WINAPI CryptGetUserKey(_In_ HCRYPTPROV, _In_ DWORD, _Out_ HCRYPTKEY *); + +WINADVAPI +BOOL +WINAPI +CryptHashData( + _In_ HCRYPTHASH hHash, + _In_reads_bytes_(dwDataLen) CONST BYTE *pbData, + _In_ DWORD dwDataLen, + _In_ DWORD dwFlags); + +WINADVAPI BOOL WINAPI CryptHashSessionKey(_In_ HCRYPTHASH, _In_ HCRYPTKEY, _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptImportKey( + _In_ HCRYPTPROV hProv, + _In_reads_bytes_(dwDataLen) CONST BYTE *pbData, + _In_ DWORD dwDataLen, + _In_ HCRYPTKEY hPubKey, + _In_ DWORD dwFlags, + _Out_ HCRYPTKEY *phKey); + #if (NTDDI_VERSION >= NTDDI_WINXP) -WINADVAPI BOOL WINAPI CryptReleaseContext (HCRYPTPROV, DWORD); +WINADVAPI BOOL WINAPI CryptReleaseContext(_In_ HCRYPTPROV, _In_ DWORD); #else -WINADVAPI BOOL WINAPI CryptReleaseContext (HCRYPTPROV, ULONG_PTR); +WINADVAPI BOOL WINAPI CryptReleaseContext(_In_ HCRYPTPROV, _In_ ULONG_PTR); #endif -WINADVAPI BOOL WINAPI CryptSetHashParam (HCRYPTHASH, DWORD, CONST BYTE *, DWORD); -WINADVAPI BOOL WINAPI CryptSetKeyParam (HCRYPTKEY, DWORD, CONST BYTE *, DWORD); -WINADVAPI BOOL WINAPI CryptSetProviderA (LPCSTR, DWORD); -WINADVAPI BOOL WINAPI CryptSetProviderW (LPCWSTR, DWORD); -#define CryptSetProvider WINELIB_NAME_AW(CryptSetProvider) -WINADVAPI BOOL WINAPI CryptSetProviderExA (LPCSTR, DWORD, DWORD *, DWORD); -WINADVAPI BOOL WINAPI CryptSetProviderExW (LPCWSTR, DWORD, DWORD *, DWORD); -#define CryptSetProviderEx WINELIB_NAME_AW(CryptSetProviderEx) -WINADVAPI BOOL WINAPI CryptSetProvParam (HCRYPTPROV, DWORD, CONST BYTE *, DWORD); -WINADVAPI BOOL WINAPI CryptSignHashA (HCRYPTHASH, DWORD, LPCSTR, DWORD, BYTE *, DWORD *); -WINADVAPI BOOL WINAPI CryptSignHashW (HCRYPTHASH, DWORD, LPCWSTR, DWORD, BYTE *, DWORD *); -#define CryptSignHash WINELIB_NAME_AW(CryptSignHash) -WINADVAPI BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH, CONST BYTE *, DWORD, HCRYPTKEY, LPCSTR, DWORD); -WINADVAPI BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH, CONST BYTE *, DWORD, HCRYPTKEY, LPCWSTR, DWORD); -#define CryptVerifySignature WINELIB_NAME_AW(CryptVerifySignature) + +WINADVAPI +BOOL +WINAPI +CryptSetHashParam( + _In_ HCRYPTHASH, + _In_ DWORD, + _In_ CONST BYTE *, + _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptSetKeyParam( + _In_ HCRYPTKEY, + _In_ DWORD, + _In_ CONST BYTE *, + _In_ DWORD); + +WINADVAPI BOOL WINAPI CryptSetProviderA(_In_ LPCSTR, _In_ DWORD); +WINADVAPI BOOL WINAPI CryptSetProviderW(_In_ LPCWSTR, _In_ DWORD); + +#define CryptSetProvider WINELIB_NAME_AW(CryptSetProvider) + +WINADVAPI +BOOL +WINAPI +CryptSetProviderExA( + _In_ LPCSTR, + _In_ DWORD, + _Reserved_ DWORD *, + _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptSetProviderExW( + _In_ LPCWSTR, + _In_ DWORD, + _Reserved_ DWORD *, + _In_ DWORD); + +#define CryptSetProviderEx WINELIB_NAME_AW(CryptSetProviderEx) + +WINADVAPI BOOL WINAPI CryptSetProvParam(_In_ HCRYPTPROV, _In_ DWORD, _In_ CONST BYTE *, _In_ DWORD); + +WINADVAPI +BOOL +WINAPI +CryptSignHashA( + _In_ HCRYPTHASH hHash, + _In_ DWORD dwKeySpec, + _In_opt_ LPCSTR szDescription, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pdwSigLen, *pdwSigLen) BYTE *pbSignature, + _Inout_ DWORD *pdwSigLen); + +WINADVAPI +BOOL +WINAPI +CryptSignHashW( + _In_ HCRYPTHASH hHash, + _In_ DWORD dwKeySpec, + _In_opt_ LPCWSTR szDescription, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pdwSigLen, *pdwSigLen) BYTE *pbSignature, + _Inout_ DWORD *pdwSigLen); + +#define CryptSignHash WINELIB_NAME_AW(CryptSignHash) + +WINADVAPI +BOOL +WINAPI +CryptVerifySignatureA( + _In_ HCRYPTHASH hHash, + _In_reads_bytes_(dwSigLen) CONST BYTE *pbSignature, + _In_ DWORD dwSigLen, + _In_ HCRYPTKEY hPubKey, + _In_opt_ LPCSTR szDescription, + _In_ DWORD dwFlags); + +WINADVAPI +BOOL +WINAPI +CryptVerifySignatureW( + _In_ HCRYPTHASH hHash, + _In_reads_bytes_(dwSigLen) CONST BYTE *pbSignature, + _In_ DWORD dwSigLen, + _In_ HCRYPTKEY hPubKey, + _In_opt_ LPCWSTR szDescription, + _In_ DWORD dwFlags); + +#define CryptVerifySignature WINELIB_NAME_AW(CryptVerifySignature) /* crypt32.dll functions */ -LPVOID WINAPI CryptMemAlloc(ULONG cbSize) __WINE_ALLOC_SIZE(1); -LPVOID WINAPI CryptMemRealloc(LPVOID pv, ULONG cbSize) __WINE_ALLOC_SIZE(2); -VOID WINAPI CryptMemFree(LPVOID pv); +LPVOID WINAPI CryptMemAlloc(_In_ ULONG cbSize) __WINE_ALLOC_SIZE(1); +LPVOID WINAPI CryptMemRealloc(_In_opt_ LPVOID pv, _In_ ULONG cbSize) __WINE_ALLOC_SIZE(2); +VOID WINAPI CryptMemFree(_In_opt_ LPVOID pv); + +_Success_(return != 0) +BOOL +WINAPI +CryptBinaryToStringA( + _In_reads_bytes_(cbBinary) const BYTE *pbBinary, + _In_ DWORD cbBinary, + _In_ DWORD dwFlags, + _Out_writes_to_opt_(*pcchString, *pcchString) LPSTR pszString, + _Inout_ DWORD *pcchString); + +_Success_(return != 0) +BOOL +WINAPI +CryptBinaryToStringW( + _In_reads_bytes_(cbBinary) const BYTE *pbBinary, + _In_ DWORD cbBinary, + _In_ DWORD dwFlags, + _Out_writes_to_opt_(*pcchString, *pcchString) LPWSTR pszString, + _Inout_ DWORD *pcchString); -BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary, - DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString); -BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary, - DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString); #define CryptBinaryToString WINELIB_NAME_AW(CryptBinaryToString) -BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString, - DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, - DWORD *pdwSkip, DWORD *pdwFlags); -BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString, - DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, - DWORD *pdwSkip, DWORD *pdwFlags); +BOOL +WINAPI +CryptStringToBinaryA( + _In_reads_(cchString) LPCSTR pszString, + _In_ DWORD cchString, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbBinary, *pcbBinary) BYTE *pbBinary, + _Inout_ DWORD *pcbBinary, + _Out_opt_ DWORD *pdwSkip, + _Out_opt_ DWORD *pdwFlags); + +BOOL +WINAPI +CryptStringToBinaryW( + _In_reads_(cchString) LPCWSTR pszString, + _In_ DWORD cchString, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbBinary, *pcbBinary) BYTE *pbBinary, + _Inout_ DWORD *pcbBinary, + _Out_opt_ DWORD *pdwSkip, + _Out_opt_ DWORD *pdwFlags); + #define CryptStringToBinary WINELIB_NAME_AW(CryptStringToBinary) -BOOL WINAPI CryptCreateAsyncHandle(DWORD dwFlags, PHCRYPTASYNC phAsync); -BOOL WINAPI CryptSetAsyncParam(HCRYPTASYNC hAsync, LPSTR pszParamOid, - LPVOID pvParam, PFN_CRYPT_ASYNC_PARAM_FREE_FUNC pfnFree); -BOOL WINAPI CryptGetAsyncParam(HCRYPTASYNC hAsync, LPSTR pszParamOid, - LPVOID *ppvParam, PFN_CRYPT_ASYNC_PARAM_FREE_FUNC *ppfnFree); -BOOL WINAPI CryptCloseAsyncHandle(HCRYPTASYNC hAsync); +BOOL +WINAPI +CryptCreateAsyncHandle( + _In_ DWORD dwFlags, + _Out_ PHCRYPTASYNC phAsync); -BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD,LPCSTR,DWORD,LPCWSTR); -BOOL WINAPI CryptRegisterOIDFunction(DWORD,LPCSTR,LPCSTR,LPCWSTR,LPCSTR); -BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID, LPCWSTR szValueName, DWORD *pdwValueType, - BYTE *pbValueData, DWORD *pcbValueData); -BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType, - const BYTE *pbValueData, DWORD cbValueData); -BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD,LPCSTR,LPCWSTR); -BOOL WINAPI CryptUnregisterOIDFunction(DWORD,LPCSTR,LPCSTR); -BOOL WINAPI CryptEnumOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID, DWORD dwFlags, void *pvArg, - PFN_CRYPT_ENUM_OID_FUNC pfnEnumOIDFunc); -HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR,DWORD); -BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet, - DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList); -BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, - DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr, - HCRYPTOIDFUNCADDR *phFuncAddr); -BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, - DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr, - HCRYPTOIDFUNCADDR *phFuncAddr); -BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, - DWORD dwFlags); -BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, - DWORD dwEncodingType, LPCSTR pszFuncName, DWORD cFuncEntry, - const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], DWORD dwFlags); -BOOL WINAPI CryptInstallDefaultContext(HCRYPTPROV hCryptProv, - DWORD dwDefaultType, const void *pvDefaultPara, DWORD dwFlags, - void *pvReserved, HCRYPTDEFAULTCONTEXT *phDefaultContext); -BOOL WINAPI CryptUninstallDefaultContext(HCRYPTDEFAULTCONTEXT hDefaultContext, - DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptSetAsyncParam( + _In_ HCRYPTASYNC hAsync, + _In_ LPSTR pszParamOid, + _In_opt_ LPVOID pvParam, + __callback PFN_CRYPT_ASYNC_PARAM_FREE_FUNC pfnFree); -BOOL WINAPI CryptEnumOIDInfo(DWORD dwGroupId, DWORD dwFlags, void *pvArg, - PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo); -PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, - DWORD dwGroupId); -BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO pInfo, DWORD dwFlags); -BOOL WINAPI CryptUnregisterOIDInfo(PCCRYPT_OID_INFO pInfo); +BOOL +WINAPI +CryptGetAsyncParam( + _In_ HCRYPTASYNC hAsync, + _In_ LPSTR pszParamOid, + _Outptr_opt_result_maybenull_ LPVOID* ppvParam, + _Outptr_opt_result_maybenull_ __callback PFN_CRYPT_ASYNC_PARAM_FREE_FUNC* ppfnFree); -LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName); +BOOL +WINAPI +CryptRegisterDefaultOIDFunction( + _In_ DWORD, + _In_ LPCSTR, + _In_ DWORD, + _In_ LPCWSTR); -LPCSTR WINAPI CertAlgIdToOID(DWORD dwAlgId); -DWORD WINAPI CertOIDToAlgId(LPCSTR pszObjId); +BOOL +WINAPI +CryptRegisterOIDFunction( + _In_ DWORD, + _In_ LPCSTR, + _In_ LPCSTR, + _In_opt_ LPCWSTR, + _In_opt_ LPCSTR); + +BOOL +WINAPI +CryptGetOIDFunctionValue( + _In_ DWORD dwEncodingType, + _In_ LPCSTR pszFuncName, + _In_ LPCSTR pszOID, + _In_opt_ LPCWSTR pwszValueName, + _Out_opt_ DWORD *pdwValueType, + _Out_writes_bytes_to_opt_(*pcbValueData, *pcbValueData) BYTE *pbValueData, + _Inout_opt_ DWORD *pcbValueData); + +BOOL +WINAPI +CryptSetOIDFunctionValue( + _In_ DWORD dwEncodingType, + _In_ LPCSTR pszFuncName, + _In_ LPCSTR pszOID, + _In_opt_ LPCWSTR pwszValueName, + _In_ DWORD dwValueType, + _In_reads_bytes_opt_(cbValueData) const BYTE *pbValueData, + _In_ DWORD cbValueData); + +BOOL WINAPI CryptUnregisterDefaultOIDFunction(_In_ DWORD, _In_ LPCSTR, _In_ LPCWSTR); +BOOL WINAPI CryptUnregisterOIDFunction(_In_ DWORD, _In_ LPCSTR, _In_ LPCSTR); + +BOOL +WINAPI +CryptEnumOIDFunction( + _In_ DWORD dwEncodingType, + _In_opt_ LPCSTR pszFuncName, + _In_opt_ LPCSTR pszOID, + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg, + __callback PFN_CRYPT_ENUM_OID_FUNC pfnEnumOIDFunc); + +HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(_In_ LPCSTR, _In_ DWORD); + +_Success_(return != 0) +BOOL +WINAPI +CryptGetDefaultOIDDllList( + _In_ HCRYPTOIDFUNCSET hFuncSet, + _In_ DWORD dwEncodingType, + _Out_writes_to_opt_(*pcchDllList, *pcchDllList) _Post_ _NullNull_terminated_ WCHAR *pwszDllList, + _Inout_ DWORD *pcchDllList); + +_Success_(return != 0) +BOOL +WINAPI +CryptGetDefaultOIDFunctionAddress( + _In_ HCRYPTOIDFUNCSET hFuncSet, + _In_ DWORD dwEncodingType, + _In_opt_ LPCWSTR pwszDll, + _In_ DWORD dwFlags, + _Outptr_ void **ppvFuncAddr, + _Inout_ HCRYPTOIDFUNCADDR *phFuncAddr); + +_Success_(return != 0) +BOOL +WINAPI +CryptGetOIDFunctionAddress( + _In_ HCRYPTOIDFUNCSET hFuncSet, + _In_ DWORD dwEncodingType, + _In_ LPCSTR pszOID, + _In_ DWORD dwFlags, + _Outptr_ void **ppvFuncAddr, + _Out_ HCRYPTOIDFUNCADDR *phFuncAddr); + +BOOL +WINAPI +CryptFreeOIDFunctionAddress( + _In_ HCRYPTOIDFUNCADDR hFuncAddr, + _In_ DWORD dwFlags); + +BOOL +WINAPI +CryptInstallOIDFunctionAddress( + _In_opt_ HMODULE hModule, + _In_ DWORD dwEncodingType, + _In_ LPCSTR pszFuncName, + _In_ DWORD cFuncEntry, + _In_reads_(cFuncEntry) const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], + _In_ DWORD dwFlags); + +BOOL +WINAPI +CryptInstallDefaultContext( + _In_ HCRYPTPROV hCryptProv, + _In_ DWORD dwDefaultType, + _In_opt_ const void *pvDefaultPara, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved, + _Out_ HCRYPTDEFAULTCONTEXT *phDefaultContext); + +BOOL +WINAPI +CryptUninstallDefaultContext( + _In_opt_ HCRYPTDEFAULTCONTEXT hDefaultContext, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); + +BOOL +WINAPI +CryptEnumOIDInfo( + _In_ DWORD dwGroupId, + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg, + __callback PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo); + +PCCRYPT_OID_INFO +WINAPI +CryptFindOIDInfo( + _In_ DWORD dwKeyType, + _In_ void *pvKey, + _In_ DWORD dwGroupId); + +BOOL WINAPI CryptRegisterOIDInfo(_In_ PCCRYPT_OID_INFO pInfo, _In_ DWORD dwFlags); +BOOL WINAPI CryptUnregisterOIDInfo(_In_ PCCRYPT_OID_INFO pInfo); + +LPCWSTR WINAPI CryptFindLocalizedName(_In_ LPCWSTR pwszCryptName); + +LPCSTR WINAPI CertAlgIdToOID(_In_ DWORD dwAlgId); +DWORD WINAPI CertOIDToAlgId(_In_ LPCSTR pszObjId); /* cert store functions */ -HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, DWORD dwEncodingType, - HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const void *pvPara); +_Must_inspect_result_ +HCERTSTORE +WINAPI +CertOpenStore( + _In_ LPCSTR lpszStoreProvider, + _In_ DWORD dwEncodingType, + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwFlags, + _In_opt_ const void *pvPara); + +HCERTSTORE +WINAPI +CertOpenSystemStoreA( + _In_opt_ HCRYPTPROV_LEGACY hProv, + _In_ LPCSTR szSubsystemProtocol); + +HCERTSTORE +WINAPI +CertOpenSystemStoreW( + _In_opt_ HCRYPTPROV_LEGACY hProv, + _In_ LPCWSTR szSubSystemProtocol); -HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv, - LPCSTR szSubSystemProtocol); -HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, - LPCWSTR szSubSystemProtocol); #define CertOpenSystemStore WINELIB_NAME_AW(CertOpenSystemStore) -PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pPrev); +PCCERT_CONTEXT +WINAPI +CertEnumCertificatesInStore( + _In_ HCERTSTORE hCertStore, + _In_opt_ PCCERT_CONTEXT pPrev); -PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore, - PCCRL_CONTEXT pPrev); +PCCRL_CONTEXT +WINAPI +CertEnumCRLsInStore( + _In_ HCERTSTORE hCertStore, + _In_opt_ PCCRL_CONTEXT pPrevCrlContext); -PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore, - PCCTL_CONTEXT pPrev); +PCCTL_CONTEXT +WINAPI +CertEnumCTLsInStore( + _In_ HCERTSTORE hCertStore, + _In_opt_ PCCTL_CONTEXT pPrevCtlContext); -BOOL WINAPI CertEnumSystemStoreLocation(DWORD dwFlags, void *pvArg, - PFN_CERT_ENUM_SYSTEM_STORE_LOCATION pfnEnum); +BOOL +WINAPI +CertEnumSystemStoreLocation( + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg, + __callback PFN_CERT_ENUM_SYSTEM_STORE_LOCATION pfnEnum); -BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara, - void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum); +BOOL +WINAPI +CertEnumSystemStore( + _In_ DWORD dwFlags, + _In_opt_ void *pvSystemStoreLocationPara, + _Inout_opt_ void *pvArg, + __callback PFN_CERT_ENUM_SYSTEM_STORE pfnEnum); -BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags, - void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum); +BOOL +WINAPI +CertEnumPhysicalStore( + _In_ const void *pvSystemStore, + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg, + __callback PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum); -BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags, - LPCWSTR pwszStoreName, PCERT_PHYSICAL_STORE_INFO pStoreInfo, void *pvReserved); +BOOL +WINAPI +CertRegisterPhysicalStore( + _In_ const void *pvSystemStore, + _In_ DWORD dwFlags, + _In_ LPCWSTR pwszStoreName, + _In_ PCERT_PHYSICAL_STORE_INFO pStoreInfo, + _Reserved_ void *pvReserved); -BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, - DWORD dwSaveAs, DWORD dwSaveTo, void* pvSaveToPara, DWORD dwFlags); +BOOL +WINAPI +CertSaveStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwEncodingType, + _In_ DWORD dwSaveAs, + _In_ DWORD dwSaveTo, + _Inout_ void *pvSaveToPara, + _In_ DWORD dwFlags); -BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, - HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority); +BOOL +WINAPI +CertAddStoreToCollection( + _In_ HCERTSTORE hCollectionStore, + _In_opt_ HCERTSTORE hSiblingStore, + _In_ DWORD dwUpdateFlags, + _In_ DWORD dwPriority); -void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore, - HCERTSTORE hSiblingStore); +void +WINAPI +CertRemoveStoreFromCollection( + _In_ HCERTSTORE hCollectionStore, + _In_ HCERTSTORE hSiblingStore); -BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig, - HCERTCHAINENGINE *phChainEngine); +_Success_(return != 0) +BOOL +WINAPI +CertCreateCertificateChainEngine( + _In_ PCERT_CHAIN_ENGINE_CONFIG pConfig, + _Out_ HCERTCHAINENGINE *phChainEngine); -BOOL WINAPI CertResyncCertificateChainEngine(HCERTCHAINENGINE hChainEngine); +BOOL WINAPI CertResyncCertificateChainEngine(_In_opt_ HCERTCHAINENGINE hChainEngine); -VOID WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine); +VOID WINAPI CertFreeCertificateChainEngine(_In_opt_ HCERTCHAINENGINE hChainEngine); -BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, - PCCERT_CONTEXT pCertContext, LPFILETIME pTime, HCERTSTORE hAdditionalStore, - PCERT_CHAIN_PARA pChainPara, DWORD dwFlags, LPVOID pvReserved, - PCCERT_CHAIN_CONTEXT *ppChainContext); +_Success_(return != 0) +BOOL +WINAPI +CertGetCertificateChain( + _In_opt_ HCERTCHAINENGINE hChainEngine, + _In_ PCCERT_CONTEXT pCertContext, + _In_opt_ LPFILETIME pTime, + _In_opt_ HCERTSTORE hAdditionalStore, + _In_ PCERT_CHAIN_PARA pChainPara, + _In_ DWORD dwFlags, + _Reserved_ LPVOID pvReserved, + _Out_ PCCERT_CHAIN_CONTEXT* ppChainContext); -PCCERT_CHAIN_CONTEXT WINAPI CertDuplicateCertificateChain( - PCCERT_CHAIN_CONTEXT pChainContext); +PCCERT_CHAIN_CONTEXT +WINAPI +CertDuplicateCertificateChain( + _In_ PCCERT_CHAIN_CONTEXT pChainContext); -VOID WINAPI CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext); +VOID WINAPI CertFreeCertificateChain(_In_ PCCERT_CHAIN_CONTEXT pChainContext); -PCCERT_CHAIN_CONTEXT WINAPI CertFindChainInStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, - const void *pvFindPara, PCCERT_CHAIN_CONTEXT pPrevChainContext); +PCCERT_CHAIN_CONTEXT +WINAPI +CertFindChainInStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwFindFlags, + _In_ DWORD dwFindType, + _In_opt_ const void *pvFindPara, + _In_opt_ PCCERT_CHAIN_CONTEXT pPrevChainContext); -BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID, - PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, - PCERT_CHAIN_POLICY_STATUS pPolicyStatus); +BOOL +WINAPI +CertVerifyCertificateChainPolicy( + _In_ LPCSTR pszPolicyOID, + _In_ PCCERT_CHAIN_CONTEXT pChainContext, + _In_ PCERT_CHAIN_POLICY_PARA pPolicyPara, + _Inout_ PCERT_CHAIN_POLICY_STATUS pPolicyStatus); -DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext, - DWORD dwPropId); +DWORD +WINAPI +CertEnumCertificateContextProperties( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwPropId); -BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, - DWORD dwPropId, void *pvData, DWORD *pcbData); +BOOL +WINAPI +CertGetCertificateContextProperty( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwPropId, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -BOOL WINAPI CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext, - DWORD dwPropId, DWORD dwFlags, const void *pvData); +BOOL +WINAPI +CertSetCertificateContextProperty( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext, - DWORD dwPropId); +DWORD +WINAPI +CertEnumCRLContextProperties( + _In_ PCCRL_CONTEXT pCRLContext, + _In_ DWORD dwPropId); -BOOL WINAPI CertGetCRLContextProperty(PCCRL_CONTEXT pCRLContext, - DWORD dwPropId, void *pvData, DWORD *pcbData); +BOOL +WINAPI +CertGetCRLContextProperty( + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwPropId, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext, - DWORD dwPropId, DWORD dwFlags, const void *pvData); +BOOL +WINAPI +CertSetCRLContextProperty( + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext, - DWORD dwPropId); +DWORD +WINAPI +CertEnumCTLContextProperties( + _In_ PCCTL_CONTEXT pCTLContext, + _In_ DWORD dwPropId); -BOOL WINAPI CertEnumSubjectInSortedCTL(PCCTL_CONTEXT pCTLContext, - void **ppvNextSubject, PCRYPT_DER_BLOB pSubjectIdentifier, - PCRYPT_DER_BLOB pEncodedAttributes); +BOOL +WINAPI +CertEnumSubjectInSortedCTL( + _In_ PCCTL_CONTEXT pCtlContext, + _Inout_ void **ppvNextSubject, + _Out_opt_ PCRYPT_DER_BLOB pSubjectIdentifier, + _Out_opt_ PCRYPT_DER_BLOB pEncodedAttributes); -BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext, - DWORD dwPropId, void *pvData, DWORD *pcbData); +BOOL +WINAPI +CertGetCTLContextProperty( + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwPropId, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext, - DWORD dwPropId, DWORD dwFlags, const void *pvData); +BOOL +WINAPI +CertSetCTLContextProperty( + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, - void *pvData, DWORD *pcbData); +_Success_(return != 0) +BOOL +WINAPI +CertGetStoreProperty( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwPropId, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, - DWORD dwFlags, const void *pvData); +BOOL +WINAPI +CertSetStoreProperty( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwPropId, + _In_ DWORD dwFlags, + _In_opt_ const void *pvData); -BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags, - DWORD dwCtrlType, void const *pvCtrlPara); +BOOL +WINAPI +CertControlStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwFlags, + _In_ DWORD dwCtrlType, + _In_opt_ void const *pvCtrlPara); -HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore); +HCERTSTORE WINAPI CertDuplicateStore(_In_ HCERTSTORE hCertStore); -BOOL WINAPI CertCloseStore( HCERTSTORE hCertStore, DWORD dwFlags ); +BOOL WINAPI CertCloseStore(_In_opt_ HCERTSTORE hCertStore, _In_ DWORD dwFlags); -BOOL WINAPI CertFreeCertificateContext( PCCERT_CONTEXT pCertContext ); +BOOL WINAPI CertFreeCertificateContext(_In_opt_ PCCERT_CONTEXT pCertContext); -BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext ); +BOOL WINAPI CertFreeCRLContext(_In_opt_ PCCRL_CONTEXT pCrlContext); -BOOL WINAPI CertFreeCTLContext( PCCTL_CONTEXT pCtlContext ); +BOOL WINAPI CertFreeCTLContext(_In_opt_ PCCTL_CONTEXT pCtlContext); -BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, - PCCERT_CONTEXT *ppStoreContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddCertificateContextToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCERT_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddCRLContextToStore( HCERTSTORE hCertStore, - PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition, - PCCRL_CONTEXT *ppStoreContext ); +_Success_(return != 0) +BOOL +WINAPI +CertAddCRLContextToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCRL_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddCTLContextToStore( HCERTSTORE hCertStore, - PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition, - PCCTL_CONTEXT *ppStoreContext ); +_Success_(return != 0) +BOOL +WINAPI +CertAddCTLContextToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCTL_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, - PCCERT_CONTEXT *ppStoreContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddCertificateLinkToStore( + _In_ HCERTSTORE hCertStore, + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCERT_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddCRLLinkToStore(HCERTSTORE hCertStore, - PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition, - PCCRL_CONTEXT *ppStoreContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddCRLLinkToStore( + _In_ HCERTSTORE hCertStore, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCRL_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddCTLLinkToStore(HCERTSTORE hCertStore, - PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition, - PCCTL_CONTEXT *ppStoreContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddCTLLinkToStore( + _In_ HCERTSTORE hCertStore, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCTL_CONTEXT *ppStoreContext); -BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded, - DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddEncodedCertificateToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbCertEncoded) const BYTE *pbCertEncoded, + _In_ DWORD cbCertEncoded, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCERT_CONTEXT *ppCertContext); + +BOOL +WINAPI +CertAddEncodedCertificateToSystemStoreA( + _In_ LPCSTR szCertStoreName, + _In_reads_bytes_(cbCertEncoded) const BYTE *pbCertEncoded, + _In_ DWORD cbCertEncoded); + +BOOL +WINAPI +CertAddEncodedCertificateToSystemStoreW( + _In_ LPCWSTR szCertStoreName, + _In_reads_bytes_(cbCertEncoded) const BYTE *pbCertEncoded, + _In_ DWORD cbCertEncoded); -BOOL WINAPI CertAddEncodedCertificateToSystemStoreA(LPCSTR pszCertStoreName, - const BYTE *pbCertEncoded, DWORD cbCertEncoded); -BOOL WINAPI CertAddEncodedCertificateToSystemStoreW(LPCWSTR pszCertStoreName, - const BYTE *pbCertEncoded, DWORD cbCertEncoded); #define CertAddEncodedCertificateToSystemStore \ WINELIB_NAME_AW(CertAddEncodedCertificateToSystemStore) -BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded, - DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddEncodedCRLToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbCrlEncoded) const BYTE *pbCrlEncoded, + _In_ DWORD cbCrlEncoded, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCRL_CONTEXT *ppCrlContext); -BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore, - DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded, - DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddEncodedCTLToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_ DWORD dwMsgAndCertEncodingType, + _In_reads_bytes_(cbCtlEncoded) const BYTE *pbCtlEncoded, + _In_ DWORD cbCtlEncoded, + _In_ DWORD dwAddDisposition, + _Outptr_opt_ PCCTL_CONTEXT *ppCtlContext); -BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore, - const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags, - DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext); +_Success_(return != 0) +BOOL +WINAPI +CertAddSerializedElementToStore( + _In_opt_ HCERTSTORE hCertStore, + _In_reads_bytes_(cbElement) const BYTE *pbElement, + _In_ DWORD cbElement, + _In_ DWORD dwAddDisposition, + _In_ DWORD dwFlags, + _In_ DWORD dwContextTypeFlags, + _Out_opt_ DWORD *pdwContextType, + _Outptr_opt_ const void **ppvContext); -BOOL WINAPI CertCompareCertificate(DWORD dwCertEncodingType, - PCERT_INFO pCertId1, PCERT_INFO pCertId2); -BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType, - PCERT_NAME_BLOB pCertName1, PCERT_NAME_BLOB pCertName2); -BOOL WINAPI CertCompareIntegerBlob(PCRYPT_INTEGER_BLOB pInt1, - PCRYPT_INTEGER_BLOB pInt2); -BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, - PCERT_PUBLIC_KEY_INFO pPublicKey1, PCERT_PUBLIC_KEY_INFO pPublicKey2); -DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType, - PCERT_PUBLIC_KEY_INFO pPublicKey); +BOOL +WINAPI +CertCompareCertificate( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_INFO pCertId1, + _In_ PCERT_INFO pCertId2); -const void * WINAPI CertCreateContext(DWORD dwContextType, DWORD dwEncodingType, - const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, - PCERT_CREATE_CONTEXT_PARA pCreatePara); +BOOL +WINAPI +CertCompareCertificateName( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_NAME_BLOB pCertName1, + _In_ PCERT_NAME_BLOB pCertName2); -PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, - const BYTE *pbCertEncoded, DWORD cbCertEncoded); +BOOL +WINAPI +CertCompareIntegerBlob( + _In_ PCRYPT_INTEGER_BLOB pInt1, + _In_ PCRYPT_INTEGER_BLOB pInt2); -PCCRL_CONTEXT WINAPI CertCreateCRLContext( DWORD dwCertEncodingType, - const BYTE* pbCrlEncoded, DWORD cbCrlEncoded); +BOOL +WINAPI +CertComparePublicKeyInfo( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_PUBLIC_KEY_INFO pPublicKey1, + _In_ PCERT_PUBLIC_KEY_INFO pPublicKey2); -PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType, - const BYTE *pbCtlEncoded, DWORD cbCtlEncoded); +DWORD +WINAPI +CertGetPublicKeyLength( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_PUBLIC_KEY_INFO pPublicKey); -PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv, - PCERT_NAME_BLOB pSubjectIssuerBlob, DWORD dwFlags, - PCRYPT_KEY_PROV_INFO pKeyProvInfo, - PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime, - PSYSTEMTIME pEndTime, PCERT_EXTENSIONS pExtensions); +const void * +WINAPI +CertCreateContext( + _In_ DWORD dwContextType, + _In_ DWORD dwEncodingType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _In_ DWORD dwFlags, + _In_opt_ PCERT_CREATE_CONTEXT_PARA pCreatePara); -BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext); +PCCERT_CONTEXT +WINAPI +CertCreateCertificateContext( + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbCertEncoded) const BYTE *pbCertEncoded, + _In_ DWORD cbCertEncoded); -BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext); +PCCRL_CONTEXT +WINAPI +CertCreateCRLContext( + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbCrlEncoded) const BYTE *pbCrlEncoded, + _In_ DWORD cbCrlEncoded); -BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext); +PCCTL_CONTEXT +WINAPI +CertCreateCTLContext( + _In_ DWORD dwMsgAndCertEncodingType, + _In_reads_bytes_(cbCtlEncoded) const BYTE *pbCtlEncoded, + _In_ DWORD cbCtlEncoded); -PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext( - PCCERT_CONTEXT pCertContext); +PCCERT_CONTEXT +WINAPI +CertCreateSelfSignCertificate( + _In_opt_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv, + _In_ PCERT_NAME_BLOB pSubjectIssuerBlob, + _In_ DWORD dwFlags, + _In_opt_ PCRYPT_KEY_PROV_INFO pKeyProvInfo, + _In_opt_ PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, + _In_opt_ PSYSTEMTIME pStartTime, + _In_opt_ PSYSTEMTIME pEndTime, + _In_opt_ PCERT_EXTENSIONS pExtensions); -PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(PCCRL_CONTEXT pCrlContext); +BOOL WINAPI CertDeleteCertificateFromStore(_In_ PCCERT_CONTEXT pCertContext); -PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext); +BOOL WINAPI CertDeleteCRLFromStore(_In_ PCCRL_CONTEXT pCrlContext); -PCCERT_CONTEXT WINAPI CertFindCertificateInStore( HCERTSTORE hCertStore, - DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, - const void *pvFindPara, PCCERT_CONTEXT pPrevCertContext ); +BOOL WINAPI CertDeleteCTLFromStore(_In_ PCCTL_CONTEXT pCtlContext); -PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, - const void *pvFindPara, PCCRL_CONTEXT pPrevCrlContext); +PCCERT_CONTEXT +WINAPI +CertDuplicateCertificateContext( + _In_opt_ PCCERT_CONTEXT pCertContext); -PCCTL_CONTEXT WINAPI CertFindCTLInStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, - const void *pvFindPara, PCCTL_CONTEXT pPrevCtlContext); +PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(_In_opt_ PCCRL_CONTEXT pCrlContext); -PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext, - DWORD *pdwFlags); +PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(_In_opt_ PCCTL_CONTEXT pCtlContext); -PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore, - DWORD dwCertEncodingType, PCERT_INFO pCertId); +PCCERT_CONTEXT +WINAPI +CertFindCertificateInStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwFindFlags, + _In_ DWORD dwFindType, + _In_opt_ const void *pvFindPara, + _In_opt_ PCCERT_CONTEXT pPrevCertContext); -PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pIssuerContext, PCCRL_CONTEXT pPrevCrlContext, DWORD *pdwFlags); +PCCRL_CONTEXT +WINAPI +CertFindCRLInStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwFindFlags, + _In_ DWORD dwFindType, + _In_opt_ const void *pvFindPara, + _In_opt_ PCCRL_CONTEXT pPrevCrlContext); -BOOL WINAPI CertSerializeCertificateStoreElement(PCCERT_CONTEXT pCertContext, - DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement); +PCCTL_CONTEXT +WINAPI +CertFindCTLInStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwMsgAndCertEncodingType, + _In_ DWORD dwFindFlags, + _In_ DWORD dwFindType, + _In_opt_ const void *pvFindPara, + _In_opt_ PCCTL_CONTEXT pPrevCtlContext); -BOOL WINAPI CertSerializeCRLStoreElement(PCCRL_CONTEXT pCrlContext, - DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement); +PCCERT_CONTEXT +WINAPI +CertGetIssuerCertificateFromStore( + _In_ HCERTSTORE hCertStore, + _In_ PCCERT_CONTEXT pSubjectContext, + _In_opt_ PCCERT_CONTEXT pPrevIssuerContext, + _Inout_ DWORD *pdwFlags); -BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext, - DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement); +PCCERT_CONTEXT +WINAPI +CertGetSubjectCertificateFromStore( + _In_ HCERTSTORE hCertStore, + _In_ DWORD dwCertEncodingType, + _In_ PCERT_INFO pCertId); -BOOL WINAPI CertGetIntendedKeyUsage(DWORD dwCertEncodingType, - PCERT_INFO pCertInfo, BYTE *pbKeyUsage, DWORD cbKeyUsage); +PCCRL_CONTEXT +WINAPI +CertGetCRLFromStore( + _In_ HCERTSTORE hCertStore, + _In_opt_ PCCERT_CONTEXT pIssuerContext, + _In_opt_ PCCRL_CONTEXT pPrevCrlContext, + _Inout_ DWORD *pdwFlags); -BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags, - PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage); -BOOL WINAPI CertSetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, - PCERT_ENHKEY_USAGE pUsage); -BOOL WINAPI CertAddEnhancedKeyUsageIdentifier(PCCERT_CONTEXT pCertContext, - LPCSTR pszUsageIdentifier); -BOOL WINAPI CertRemoveEnhancedKeyUsageIdentifier(PCCERT_CONTEXT pCertContext, - LPCSTR pszUsageIdentifier); -BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts, - int *cNumOIDs, LPSTR *rghOIDs, DWORD *pcbOIDs); +BOOL +WINAPI +CertSerializeCertificateStoreElement( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbElement, *pcbElement) BYTE *pbElement, + _Inout_ DWORD *pcbElement); -BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, - const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded); -BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, - const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, - void *pvEncoded, DWORD *pcbEncoded); +BOOL +WINAPI +CertSerializeCRLStoreElement( + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbElement, *pcbElement) BYTE *pbElement, + _Inout_ DWORD *pcbElement); -BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, - const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, - DWORD *pcbStructInfo); -BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, - const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, - PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo); +BOOL +WINAPI +CertSerializeCTLStoreElement( + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbElement, *pcbElement) BYTE *pbElement, + _Inout_ DWORD *pcbElement); -BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType, - DWORD dwFormatStrType, void *pFormatStruct, LPCSTR lpszStructType, - const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat, DWORD *pcbFormat); +BOOL +WINAPI +CertGetIntendedKeyUsage( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_INFO pCertInfo, + _Out_writes_bytes_all_(cbKeyUsage) BYTE *pbKeyUsage, + _In_ DWORD cbKeyUsage); -BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, - DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, - DWORD *pcbComputedHash); +BOOL +WINAPI +CertGetEnhancedKeyUsage( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbUsage, *pcbUsage) PCERT_ENHKEY_USAGE pUsage, + _Inout_ DWORD *pcbUsage); -BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, - DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, - BYTE *pbComputedHash, DWORD *pcbComputedHash); +BOOL +WINAPI +CertSetEnhancedKeyUsage( + _In_ PCCERT_CONTEXT pCertContext, + _In_opt_ PCERT_ENHKEY_USAGE pUsage); -BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, - const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, - DWORD *pcbComputedHash); +BOOL +WINAPI +CertAddEnhancedKeyUsageIdentifier( + _In_ PCCERT_CONTEXT pCertContext, + _In_ LPCSTR pszUsageIdentifier); -BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void* pvObject, - DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags, - DWORD dwFlags, DWORD* pdwMsgAndCertEncodingType, DWORD* pdwContentType, - DWORD* pdwFormatType, HCERTSTORE* phCertStore, HCRYPTMSG* phMsg, - const void** ppvContext); +BOOL +WINAPI +CertRemoveEnhancedKeyUsageIdentifier( + _In_ PCCERT_CONTEXT pCertContext, + _In_ LPCSTR pszUsageIdentifier); -BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec, - DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned, - DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, - const void *pvHashAuxInfo, BYTE *pbSignature, DWORD *pcbSignature); +_Success_(return != 0) +BOOL +WINAPI +CertGetValidUsages( + _In_ DWORD cCerts, + _In_reads_(cCerts) PCCERT_CONTEXT *rghCerts, + _Out_ int *cNumOIDs, + _Out_writes_bytes_to_opt_(*pcbOIDs, *pcbOIDs) LPSTR *rghOIDs, + _Inout_ DWORD *pcbOIDs); -BOOL WINAPI CryptSignAndEncodeCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, - DWORD dwKeySpec, DWORD dwCertEncodingType, LPCSTR lpszStructType, - const void *pvStructInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, - const void *pvHashAuxInfo, BYTE *pbEncoded, DWORD *pcbEncoded); +BOOL +WINAPI +CryptEncodeObject( + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR lpszStructType, + _In_ const void *pvStructInfo, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded); -BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV_LEGACY hCryptProv, - DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, - PCERT_PUBLIC_KEY_INFO pPublicKey); +BOOL +WINAPI +CryptEncodeObjectEx( + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR lpszStructType, + _In_ const void *pvStructInfo, + _In_ DWORD dwFlags, + _In_opt_ PCRYPT_ENCODE_PARA pEncodePara, + _Out_opt_ void *pvEncoded, + _Inout_ DWORD *pcbEncoded); -BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv, - DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject, - DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptDecodeObject( + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR lpszStructType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbStructInfo, *pcbStructInfo) void *pvStructInfo, + _Inout_ DWORD *pcbStructInfo); -PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr, - CRYPT_ATTRIBUTE rgAttr[]); -PCERT_EXTENSION WINAPI CertFindExtension(LPCSTR pszObjId, DWORD cExtensions, - CERT_EXTENSION rgExtensions[]); -PCERT_RDN_ATTR WINAPI CertFindRDNAttr(LPCSTR pszObjId, PCERT_NAME_INFO pName); +BOOL +WINAPI +CryptDecodeObjectEx( + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR lpszStructType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _In_ DWORD dwFlags, + _In_opt_ PCRYPT_DECODE_PARA pDecodePara, + _Out_opt_ void *pvStructInfo, + _Inout_ DWORD *pcbStructInfo); -BOOL WINAPI CertFindSubjectInSortedCTL(PCRYPT_DATA_BLOB pSubjectIdentifier, - PCCTL_CONTEXT pCtlContext, DWORD dwFlags, void *pvReserved, - PCRYPT_DER_BLOB pEncodedAttributes); +BOOL +WINAPI +CryptFormatObject( + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwFormatType, + _In_ DWORD dwFormatStrType, + _In_opt_ void *pFormatStruct, + _In_opt_ LPCSTR lpszStructType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _At_((WCHAR *) pbFormat, _Out_writes_bytes_to_opt_(*pcbFormat, *pcbFormat)) void *pbFormat, + _Inout_ DWORD *pcbFormat); -BOOL WINAPI CertIsRDNAttrsInCertificateName(DWORD dwCertEncodingType, - DWORD dwFlags, PCERT_NAME_BLOB pCertName, PCERT_RDN pRDN); +BOOL +WINAPI +CryptHashCertificate( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ ALG_ID Algid, + _In_ DWORD dwFlags, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_ DWORD *pcbComputedHash); -BOOL WINAPI CertIsValidCRLForCertificate(PCCERT_CONTEXT pCert, - PCCRL_CONTEXT pCrl, DWORD dwFlags, void *pvReserved); -BOOL WINAPI CertFindCertificateInCRL(PCCERT_CONTEXT pCert, - PCCRL_CONTEXT pCrlContext, DWORD dwFlags, void *pvReserved, - PCRL_ENTRY *ppCrlEntry); -BOOL WINAPI CertVerifyCRLRevocation(DWORD dwCertEncodingType, - PCERT_INFO pCertId, DWORD cCrlInfo, PCRL_INFO rgpCrlInfo[]); +BOOL +WINAPI +CryptHashPublicKeyInfo( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ ALG_ID Algid, + _In_ DWORD dwFlags, + _In_ DWORD dwCertEncodingType, + _In_ PCERT_PUBLIC_KEY_INFO pInfo, + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_ DWORD *pcbComputedHash); -BOOL WINAPI CertVerifySubjectCertificateContext(PCCERT_CONTEXT pSubject, - PCCERT_CONTEXT pIssuer, DWORD *pdwFlags); +BOOL +WINAPI +CryptHashToBeSigned( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_ DWORD *pcbComputedHash); -LONG WINAPI CertVerifyCRLTimeValidity(LPFILETIME pTimeToVerify, - PCRL_INFO pCrlInfo); -LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify, - PCERT_INFO pCertInfo); -BOOL WINAPI CertVerifyValidityNesting(PCERT_INFO pSubjectInfo, - PCERT_INFO pIssuerInfo); +BOOL +WINAPI +CryptQueryObject( + _In_ DWORD dwObjectType, + _In_ const void *pvObject, + _In_ DWORD dwExpectedContentTypeFlags, + _In_ DWORD dwExpectedFormatTypeFlags, + _In_ DWORD dwFlags, + _Out_opt_ DWORD *pdwMsgAndCertEncodingType, + _Out_opt_ DWORD *pdwContentType, + _Out_opt_ DWORD *pdwFormatType, + _Out_opt_ HCERTSTORE *phCertStore, + _Out_opt_ HCRYPTMSG *phMsg, + _Outptr_opt_result_maybenull_ const void **ppvContext); -BOOL WINAPI CertVerifyCTLUsage(DWORD dwEncodingType, DWORD dwSubjectType, - void *pvSubject, PCTL_USAGE pSubjectUsage, DWORD dwFlags, - PCTL_VERIFY_USAGE_PARA pVerifyUsagePara, - PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus); +BOOL +WINAPI +CryptSignCertificate( + _In_opt_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, + _In_opt_ DWORD dwKeySpec, + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbEncodedToBeSigned) const BYTE *pbEncodedToBeSigned, + _In_ DWORD cbEncodedToBeSigned, + _In_ PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, + _In_opt_ const void *pvHashAuxInfo, + _Out_writes_bytes_to_opt_(*pcbSignature, *pcbSignature) BYTE *pbSignature, + _Inout_ DWORD *pcbSignature); -BOOL WINAPI CertVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType, - DWORD cContext, PVOID rgpvContext[], DWORD dwFlags, - PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus); +BOOL +WINAPI +CryptSignAndEncodeCertificate( + _In_opt_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, + _In_opt_ DWORD dwKeySpec, + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR lpszStructType, + _In_ const void *pvStructInfo, + _In_ PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, + _In_opt_ const void *pvHashAuxInfo, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded); -BOOL WINAPI CryptExportPublicKeyInfo(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec, - DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo); -BOOL WINAPI CryptExportPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec, - DWORD dwCertEncodingType, LPSTR pszPublicKeyObjId, DWORD dwFlags, - void *pvAuxInfo, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo); -BOOL WINAPI CryptImportPublicKeyInfo(HCRYPTPROV hCryptProv, - DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, HCRYPTKEY *phKey); -BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv, - DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, ALG_ID aiKeyAlg, - DWORD dwFlags, void *pvAuxInfo, HCRYPTKEY *phKey); +_Must_inspect_result_ +BOOL +WINAPI +CryptVerifyCertificateSignature( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwCertEncodingType, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _In_ DWORD cbEncoded, + _In_ PCERT_PUBLIC_KEY_INFO pPublicKey); -BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, - DWORD dwFlags, void *pvReserved, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProv, DWORD *pdwKeySpec, - BOOL *pfCallerFreeProv); +_Must_inspect_result_ +BOOL +WINAPI +CryptVerifyCertificateSignatureEx( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwSubjectType, + _In_ void *pvSubject, + _In_ DWORD dwIssuerType, + _In_opt_ void *pvIssuer, + _In_ DWORD dwFlags, + _Inout_opt_ void *pvExtra); -BOOL WINAPI CryptFindCertificateKeyProvInfo(PCCERT_CONTEXT pCert, - DWORD dwFlags, void *pvReserved); +PCRYPT_ATTRIBUTE +WINAPI +CertFindAttribute( + _In_ LPCSTR pszObjId, + _In_ DWORD cAttr, + _In_reads_(cAttr) CRYPT_ATTRIBUTE rgAttr[]); + +PCERT_EXTENSION +WINAPI +CertFindExtension( + _In_ LPCSTR pszObjId, + _In_ DWORD cExtensions, + _In_reads_(cExtensions) CERT_EXTENSION rgExtensions[]); + +PCERT_RDN_ATTR +WINAPI +CertFindRDNAttr( + _In_ LPCSTR pszObjId, + _In_ PCERT_NAME_INFO pName); + +BOOL +WINAPI +CertFindSubjectInSortedCTL( + _In_ PCRYPT_DATA_BLOB pSubjectIdentifier, + _In_ PCCTL_CONTEXT pCtlContext, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved, + _Out_opt_ PCRYPT_DER_BLOB pEncodedAttributes); + +BOOL +WINAPI +CertIsRDNAttrsInCertificateName( + _In_ DWORD dwCertEncodingType, + _In_ DWORD dwFlags, + _In_ PCERT_NAME_BLOB pCertName, + _In_ PCERT_RDN pRDN); + +BOOL +WINAPI +CertIsValidCRLForCertificate( + _In_ PCCERT_CONTEXT pCert, + _In_ PCCRL_CONTEXT pCrl, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); + +BOOL +WINAPI +CertFindCertificateInCRL( + _In_ PCCERT_CONTEXT pCert, + _In_ PCCRL_CONTEXT pCrlContext, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved, + _Outptr_result_maybenull_ PCRL_ENTRY *ppCrlEntry); + +BOOL +WINAPI +CertVerifyCRLRevocation( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_INFO pCertId, + _In_ DWORD cCrlInfo, + _In_reads_(cCrlInfo) PCRL_INFO rgpCrlInfo[]); + +BOOL +WINAPI +CertVerifySubjectCertificateContext( + _In_ PCCERT_CONTEXT pSubject, + _In_opt_ PCCERT_CONTEXT pIssuer, + _Inout_ DWORD *pdwFlags); + +LONG +WINAPI +CertVerifyCRLTimeValidity( + _In_opt_ LPFILETIME pTimeToVerify, + _In_ PCRL_INFO pCrlInfo); + +LONG +WINAPI +CertVerifyTimeValidity( + _In_opt_ LPFILETIME pTimeToVerify, + _In_ PCERT_INFO pCertInfo); + +BOOL +WINAPI +CertVerifyValidityNesting( + _In_ PCERT_INFO pSubjectInfo, + _In_ PCERT_INFO pIssuerInfo); + +BOOL +WINAPI +CertVerifyCTLUsage( + _In_ DWORD dwEncodingType, + _In_ DWORD dwSubjectType, + _In_ void *pvSubject, + _In_ PCTL_USAGE pSubjectUsage, + _In_ DWORD dwFlags, + _In_opt_ PCTL_VERIFY_USAGE_PARA pVerifyUsagePara, + _Inout_ PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus); + +BOOL +WINAPI +CertVerifyRevocation( + _In_ DWORD dwEncodingType, + _In_ DWORD dwRevType, + _In_ DWORD cContext, + _In_reads_(cContext) PVOID rgpvContext[], + _In_ DWORD dwFlags, + _In_opt_ PCERT_REVOCATION_PARA pRevPara, + _Inout_ PCERT_REVOCATION_STATUS pRevStatus); + +BOOL +WINAPI +CryptExportPublicKeyInfo( + _In_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, + _In_opt_ DWORD dwKeySpec, + _In_ DWORD dwCertEncodingType, + _Out_writes_bytes_to_opt_(*pcbInfo, *pcbInfo) PCERT_PUBLIC_KEY_INFO pInfo, + _Inout_ DWORD *pcbInfo); + +BOOL +WINAPI +CryptExportPublicKeyInfoEx( + _In_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, + _In_opt_ DWORD dwKeySpec, + _In_ DWORD dwCertEncodingType, + _In_opt_ LPSTR pszPublicKeyObjId, + _In_ DWORD dwFlags, + _In_opt_ void *pvAuxInfo, + _Out_writes_bytes_to_opt_(*pcbInfo, *pcbInfo) PCERT_PUBLIC_KEY_INFO pInfo, + _Inout_ DWORD *pcbInfo); + +BOOL +WINAPI +CryptImportPublicKeyInfo( + _In_ HCRYPTPROV hCryptProv, + _In_ DWORD dwCertEncodingType, + _In_ PCERT_PUBLIC_KEY_INFO pInfo, + _Out_ HCRYPTKEY *phKey); + +BOOL +WINAPI +CryptImportPublicKeyInfoEx( + _In_ HCRYPTPROV hCryptProv, + _In_ DWORD dwCertEncodingType, + _In_ PCERT_PUBLIC_KEY_INFO pInfo, + _In_ ALG_ID aiKeyAlg, + _In_ DWORD dwFlags, + _In_opt_ void *pvAuxInfo, + _Out_ HCRYPTKEY *phKey); + +BOOL +WINAPI +CryptAcquireCertificatePrivateKey( + _In_ PCCERT_CONTEXT pCert, + _In_ DWORD dwFlags, + _In_opt_ void *pvParameters, + _Out_ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProvOrNCryptKey, + _Out_opt_ DWORD *pdwKeySpec, + _Out_opt_ BOOL *pfCallerFreeProvOrNCryptKey); + +BOOL +WINAPI +CryptFindCertificateKeyProvInfo( + _In_ PCCERT_CONTEXT pCert, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); BOOL WINAPI CryptProtectData( DATA_BLOB* pDataIn, LPCWSTR szDataDescr, DATA_BLOB* pOptionalEntropy, PVOID pvReserved, @@ -4371,198 +5506,523 @@ BOOL WINAPI CryptUnprotectData( DATA_BLOB* pDataIn, LPWSTR* ppszDataDescr, DATA_BLOB* pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags, DATA_BLOB* pDataOut ); -DWORD WINAPI CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType, - DWORD dwFlags, void *pvTypePara, LPSTR pszNameString, DWORD cchNameString); -DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, - DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString); +DWORD +WINAPI +CertGetNameStringA( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwType, + _In_ DWORD dwFlags, + _In_opt_ void *pvTypePara, + _Out_writes_to_opt_(cchNameString, return) LPSTR pszNameString, + _In_ DWORD cchNameString); + +DWORD +WINAPI +CertGetNameStringW( + _In_ PCCERT_CONTEXT pCertContext, + _In_ DWORD dwType, + _In_ DWORD dwFlags, + _In_opt_ void *pvTypePara, + _Out_writes_to_opt_(cchNameString, return) LPWSTR pszNameString, + _In_ DWORD cchNameString); + #define CertGetNameString WINELIB_NAME_AW(CertGetNameString) -DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, - LPSTR psz, DWORD csz); -DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, - LPWSTR psz, DWORD csz); +DWORD +WINAPI +CertRDNValueToStrA( + _In_ DWORD dwValueType, + _In_ PCERT_RDN_VALUE_BLOB pValue, + _Out_writes_to_opt_(csz, return) LPSTR psz, + _In_ DWORD csz); + +DWORD +WINAPI +CertRDNValueToStrW( + _In_ DWORD dwValueType, + _In_ PCERT_RDN_VALUE_BLOB pValue, + _Out_writes_to_opt_(csz, return) LPWSTR psz, + _In_ DWORD csz); + #define CertRDNValueToStr WINELIB_NAME_AW(CertRDNValueToStr) -DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, - DWORD dwStrType, LPSTR psz, DWORD csz); -DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, - DWORD dwStrType, LPWSTR psz, DWORD csz); +DWORD +WINAPI +CertNameToStrA( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_NAME_BLOB pName, + _In_ DWORD dwStrType, + _Out_writes_to_opt_(csz, return) LPSTR psz, + _In_ DWORD csz); + +DWORD +WINAPI +CertNameToStrW( + _In_ DWORD dwCertEncodingType, + _In_ PCERT_NAME_BLOB pName, + _In_ DWORD dwStrType, + _Out_writes_to_opt_(csz, return) LPWSTR psz, + _In_ DWORD csz); + #define CertNameToStr WINELIB_NAME_AW(CertNameToStr) -BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500, - DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, - LPCSTR *ppszError); -BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500, - DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, - LPCWSTR *ppszError); +BOOL +WINAPI +CertStrToNameA( + _In_ DWORD dwCertEncodingType, + _In_ LPCSTR pszX500, + _In_ DWORD dwStrType, + _Reserved_ void *pvReserved, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded, + _Outptr_opt_result_maybenull_ LPCSTR *ppszError); + +BOOL +WINAPI +CertStrToNameW( + _In_ DWORD dwCertEncodingType, + _In_ LPCWSTR pszX500, + _In_ DWORD dwStrType, + _Reserved_ void *pvReserved, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded, + _Outptr_opt_result_maybenull_ LPCWSTR *ppszError); + #define CertStrToName WINELIB_NAME_AW(CertStrToName) -DWORD WINAPI CryptMsgCalculateEncodedLength(DWORD dwMsgEncodingType, - DWORD dwFlags, DWORD dwMsgType, const void *pvMsgEncodeInfo, - LPSTR pszInnerContentObjID, DWORD cbData); +DWORD +WINAPI +CryptMsgCalculateEncodedLength( + _In_ DWORD dwMsgEncodingType, + _In_ DWORD dwFlags, + _In_ DWORD dwMsgType, + _In_ void const *pvMsgEncodeInfo, + _In_opt_ LPSTR pszInnerContentObjID, + _In_ DWORD cbData); -BOOL WINAPI CryptMsgClose(HCRYPTMSG hCryptMsg); +BOOL WINAPI CryptMsgClose(_In_opt_ HCRYPTMSG hCryptMsg); -BOOL WINAPI CryptMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags, - DWORD dwCtrlType, const void *pvCtrlPara); +BOOL +WINAPI +CryptMsgControl( + _In_ HCRYPTMSG hCryptMsg, + _In_ DWORD dwFlags, + _In_ DWORD dwCtrlType, + _In_opt_ void const *pvCtrlPara); -BOOL WINAPI CryptMsgCountersign(HCRYPTMSG hCryptMsg, DWORD dwIndex, - DWORD dwCountersigners, PCMSG_SIGNER_ENCODE_INFO rgCountersigners); +BOOL +WINAPI +CryptMsgCountersign( + _In_ HCRYPTMSG hCryptMsg, + _In_ DWORD dwIndex, + _In_ DWORD cCountersigners, + _In_reads_(cCountersigners) PCMSG_SIGNER_ENCODE_INFO rgCountersigners); -BOOL WINAPI CryptMsgCountersignEncoded(DWORD dwEncodingType, PBYTE pbSignerInfo, - DWORD cbSignerInfo, DWORD cCountersigners, - PCMSG_SIGNER_ENCODE_INFO rgCountersigners, PBYTE pbCountersignature, - PDWORD pcbCountersignature); +BOOL +WINAPI +CryptMsgCountersignEncoded( + _In_ DWORD dwEncodingType, + _In_reads_bytes_(cbSignerInfo) PBYTE pbSignerInfo, + _In_ DWORD cbSignerInfo, + _In_ DWORD cCountersigners, + _In_reads_(cCountersigners) PCMSG_SIGNER_ENCODE_INFO rgCountersigners, + _Out_writes_bytes_to_opt_(*pcbCountersignature, *pcbCountersignature) PBYTE pbCountersignature, + _Inout_ PDWORD pcbCountersignature); -HCRYPTMSG WINAPI CryptMsgDuplicate(HCRYPTMSG hCryptMsg); +HCRYPTMSG WINAPI CryptMsgDuplicate(_In_opt_ HCRYPTMSG hCryptMsg); -BOOL WINAPI CryptMsgEncodeAndSignCTL(DWORD dwMsgEncodingType, - PCTL_INFO pCtlInfo, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags, - BYTE *pbEncoded, DWORD *pcbEncoded); +BOOL +WINAPI +CryptMsgEncodeAndSignCTL( + _In_ DWORD dwMsgEncodingType, + _In_ PCTL_INFO pCtlInfo, + _In_ PCMSG_SIGNED_ENCODE_INFO pSignInfo, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded); -BOOL WINAPI CryptMsgGetAndVerifySigner(HCRYPTMSG hCryptMsg, DWORD cSignerStore, - HCERTSTORE *rghSignerStore, DWORD dwFlags, PCCERT_CONTEXT *ppSigner, - DWORD *pdwSignerIndex); +_Success_(return == 0) +BOOL +WINAPI +CryptMsgGetAndVerifySigner( + _In_ HCRYPTMSG hCryptMsg, + _In_ DWORD cSignerStore, + _In_reads_opt_(cSignerStore) HCERTSTORE *rghSignerStore, + _In_ DWORD dwFlags, + _Outptr_opt_ PCCERT_CONTEXT *ppSigner, + _Inout_opt_ DWORD *pdwSignerIndex); -BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType, - DWORD dwIndex, void *pvData, DWORD *pcbData); +BOOL +WINAPI +CryptMsgGetParam( + _In_ HCRYPTMSG hCryptMsg, + _In_ DWORD dwParamType, + _In_ DWORD dwIndex, + _Out_writes_bytes_to_opt_(*pcbData, *pcbData) void *pvData, + _Inout_ DWORD *pcbData); -HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags, - DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo, - PCMSG_STREAM_INFO pStreamInfo); +HCRYPTMSG +WINAPI +CryptMsgOpenToDecode( + _In_ DWORD dwMsgEncodingType, + _In_ DWORD dwFlags, + _In_ DWORD dwMsgType, + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _Reserved_ PCERT_INFO pRecipientInfo, + _In_opt_ PCMSG_STREAM_INFO pStreamInfo); -HCRYPTMSG WINAPI CryptMsgOpenToEncode(DWORD dwMsgEncodingType, DWORD dwFlags, - DWORD dwMsgType, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID, - PCMSG_STREAM_INFO pStreamInfo); +HCRYPTMSG +WINAPI +CryptMsgOpenToEncode( + _In_ DWORD dwMsgEncodingType, + _In_ DWORD dwFlags, + _In_ DWORD dwMsgType, + _In_ void const *pvMsgEncodeInfo, + _In_opt_ LPSTR pszInnerContentObjID, + _In_opt_ PCMSG_STREAM_INFO pStreamInfo); -BOOL WINAPI CryptMsgSignCTL(DWORD dwMsgEncodingType, BYTE *pbCtlContent, - DWORD cbCtlContent, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags, - BYTE *pbEncoded, DWORD *pcbEncoded); +BOOL +WINAPI +CryptMsgSignCTL( + _In_ DWORD dwMsgEncodingType, + _In_reads_bytes_(cbCtlContent) BYTE *pbCtlContent, + _In_ DWORD cbCtlContent, + _In_ PCMSG_SIGNED_ENCODE_INFO pSignInfo, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbEncoded, *pcbEncoded) BYTE *pbEncoded, + _Inout_ DWORD *pcbEncoded); -BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData, - DWORD cbData, BOOL fFinal); +BOOL +WINAPI +CryptMsgUpdate( + _In_ HCRYPTMSG hCryptMsg, + _In_reads_bytes_opt_(cbData) const BYTE *pbData, + _In_ DWORD cbData, + _In_ BOOL fFinal); -BOOL WINAPI CryptMsgVerifyCountersignatureEncoded(HCRYPTPROV_LEGACY hCryptProv, - DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo, - PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature, - PCERT_INFO pciCountersigner); +BOOL +WINAPI +CryptMsgVerifyCountersignatureEncoded( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwEncodingType, + _In_reads_bytes_(cbSignerInfo) PBYTE pbSignerInfo, + _In_ DWORD cbSignerInfo, + _In_reads_bytes_(cbSignerInfoCountersignature) PBYTE pbSignerInfoCountersignature, + _In_ DWORD cbSignerInfoCountersignature, + _In_ PCERT_INFO pciCountersigner); -BOOL WINAPI CryptMsgVerifyCountersignatureEncodedEx(HCRYPTPROV_LEGACY hCryptProv, - DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo, - PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature, - DWORD dwSignerType, void *pvSigner, DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptMsgVerifyCountersignatureEncodedEx( + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwEncodingType, + _In_reads_bytes_(cbSignerInfo) PBYTE pbSignerInfo, + _In_ DWORD cbSignerInfo, + _In_reads_bytes_(cbSignerInfoCountersignature) PBYTE pbSignerInfoCountersignature, + _In_ DWORD cbSignerInfoCountersignature, + _In_ DWORD dwSignerType, + _In_ void *pvSigner, + _In_ DWORD dwFlags, + _Inout_opt_ void *pvExtra); -BOOL WINAPI CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara, - BOOL fDetachedSignature, DWORD cToBeSigned, const BYTE *rgpbToBeSigned[], - DWORD rgcbToBeSigned[], BYTE *pbSignedBlob, DWORD *pcbSignedBlob); -BOOL WINAPI CryptSignMessageWithKey(PCRYPT_KEY_SIGN_MESSAGE_PARA pSignPara, - const BYTE *pbToBeSigned, DWORD cbToBeSigned, BYTE *pbSignedBlob, - DWORD *pcbSignedBlob); +BOOL +WINAPI +CryptSignMessage( + _In_ PCRYPT_SIGN_MESSAGE_PARA pSignPara, + _In_ BOOL fDetachedSignature, + _In_ DWORD cToBeSigned, + _In_reads_opt_(cToBeSigned) const BYTE *rgpbToBeSigned[], + _In_reads_(cToBeSigned) DWORD rgcbToBeSigned[], + _Out_writes_bytes_to_opt_(*pcbSignedBlob, *pcbSignedBlob) BYTE *pbSignedBlob, + _Inout_ DWORD *pcbSignedBlob); -BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, - DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob, - BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert); -BOOL WINAPI CryptVerifyMessageSignatureWithKey( - PCRYPT_KEY_VERIFY_MESSAGE_PARA pVerifyPara, - PCERT_PUBLIC_KEY_INFO pPublicKeyInfo, const BYTE *pbSignedBlob, - DWORD cbSignedBlob, BYTE *pbDecoded, DWORD *pcbDecoded); +BOOL +WINAPI +CryptSignMessageWithKey( + _In_ PCRYPT_KEY_SIGN_MESSAGE_PARA pSignPara, + _In_reads_bytes_(cbToBeSigned) const BYTE *pbToBeSigned, + _In_ DWORD cbToBeSigned, + _Out_writes_bytes_to_opt_(*pcbSignedBlob, *pcbSignedBlob) BYTE *pbSignedBlob, + _Inout_ DWORD *pcbSignedBlob); -BOOL WINAPI CryptVerifyDetachedMessageSignature( - PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, - const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned, - const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[], - PCCERT_CONTEXT *ppSignerCert); -LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType, - const BYTE *pbSignedBlob, DWORD cbSignedBlob); +BOOL +WINAPI +CryptVerifyMessageSignature( + _In_ PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, + _In_ DWORD dwSignerIndex, + _In_reads_bytes_(cbSignedBlob) const BYTE *pbSignedBlob, + _In_ DWORD cbSignedBlob, + _Out_writes_bytes_to_opt_(*pcbDecoded, *pcbDecoded) BYTE *pbDecoded, + _Inout_opt_ DWORD *pcbDecoded, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppSignerCert); -BOOL WINAPI CryptEncryptMessage(PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, - DWORD cRecipientCert, PCCERT_CONTEXT rgpRecipientCert[], - const BYTE *pbToBeEncrypted, DWORD cbToBeEncrypted, BYTE *pbEncryptedBlob, - DWORD *pcbEncryptedBlob); -BOOL WINAPI CryptDecryptMessage(PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, - const BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, BYTE *pbDecrypted, - DWORD *pcbDecrypted, PCCERT_CONTEXT *ppXchgCert); +BOOL +WINAPI +CryptVerifyMessageSignatureWithKey( + _In_ PCRYPT_KEY_VERIFY_MESSAGE_PARA pVerifyPara, + _In_opt_ PCERT_PUBLIC_KEY_INFO pPublicKeyInfo, + _In_reads_bytes_(cbSignedBlob) const BYTE *pbSignedBlob, + _In_ DWORD cbSignedBlob, + _Out_writes_bytes_to_opt_(*pcbDecoded, *pcbDecoded) BYTE *pbDecoded, + _Inout_opt_ DWORD *pcbDecoded); -BOOL WINAPI CryptSignAndEncryptMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara, - PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, DWORD cRecipientCert, - PCCERT_CONTEXT rgpRecipientCert[], const BYTE *pbToBeSignedAndEncrypted, - DWORD cbToBeSignedAndEncrypted, BYTE *pbSignedAndEncryptedBlob, - DWORD *pcbSignedAndEncryptedBlob); -BOOL WINAPI CryptDecryptAndVerifyMessageSignature( - PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, - PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, - const BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, BYTE *pbDecrypted, - DWORD *pcbDecrypted, PCCERT_CONTEXT *ppXchgCert, PCCERT_CONTEXT *ppSignerCert); +BOOL +WINAPI +CryptVerifyDetachedMessageSignature( + _In_ PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, + _In_ DWORD dwSignerIndex, + _In_reads_bytes_(cbDetachedSignBlob) const BYTE *pbDetachedSignBlob, + _In_ DWORD cbDetachedSignBlob, + _In_ DWORD cToBeSigned, + _In_reads_(cToBeSigned) const BYTE *rgpbToBeSigned[], + _In_reads_(cToBeSigned) DWORD rgcbToBeSigned[], + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppSignerCert); -HCERTSTORE WINAPI CryptGetMessageCertificates(DWORD dwMsgAndCertEncodingType, - HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const BYTE *pbSignedBlob, - DWORD cbSignedBlob); +LONG +WINAPI +CryptGetMessageSignerCount( + _In_ DWORD dwMsgEncodingType, + _In_reads_bytes_(cbSignedBlob) const BYTE *pbSignedBlob, + _In_ DWORD cbSignedBlob); -BOOL WINAPI CryptDecodeMessage(DWORD dwMsgTypeFlags, - PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, - PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, - const BYTE *pbEncodedBlob, DWORD cbEncodedBlob, DWORD dwPrevInnerContentType, - DWORD *pdwMsgType, DWORD *pdwInnerContentType, BYTE *pbDecoded, - DWORD *pcbDecoded, PCCERT_CONTEXT *ppXchgCert, PCCERT_CONTEXT *ppSignerCert); +BOOL +WINAPI +CryptEncryptMessage( + _In_ PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, + _In_ DWORD cRecipientCert, + _In_reads_(cRecipientCert) PCCERT_CONTEXT rgpRecipientCert[], + _In_reads_bytes_opt_(cbToBeEncrypted) const BYTE *pbToBeEncrypted, + _In_ DWORD cbToBeEncrypted, + _Out_writes_bytes_to_opt_(*pcbEncryptedBlob, *pcbEncryptedBlob) BYTE *pbEncryptedBlob, + _Inout_ DWORD *pcbEncryptedBlob); -BOOL WINAPI CryptHashMessage(PCRYPT_HASH_MESSAGE_PARA pHashPara, - BOOL fDetachedHash, DWORD cToBeHashed, const BYTE *rgpbToBeHashed[], - DWORD rgcbToBeHashed[], BYTE *pbHashedBlob, DWORD *pcbHashedBlob, - BYTE *pbComputedHash, DWORD *pcbComputedHash); -BOOL WINAPI CryptVerifyMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, - BYTE *pbHashedBlob, DWORD cbHashedBlob, BYTE *pbToBeHashed, - DWORD *pcbToBeHashed, BYTE *pbComputedHash, DWORD *pcbComputedHash); -BOOL WINAPI CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, - BYTE *pbDetachedHashBlob, DWORD cbDetachedHashBlob, DWORD cToBeHashed, - const BYTE *rgpbToBeHashed[], DWORD rgcbToBeHashed[], BYTE *pbComputedHash, - DWORD *pcbComputedHash); +BOOL +WINAPI +CryptDecryptMessage( + _In_ PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, + _In_reads_bytes_(cbEncryptedBlob) const BYTE *pbEncryptedBlob, + _In_ DWORD cbEncryptedBlob, + _Out_writes_bytes_to_opt_(*pcbDecrypted, *pcbDecrypted) BYTE *pbDecrypted, + _Inout_opt_ DWORD *pcbDecrypted, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppXchgCert); + +BOOL +WINAPI +CryptSignAndEncryptMessage( + _In_ PCRYPT_SIGN_MESSAGE_PARA pSignPara, + _In_ PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, + _In_ DWORD cRecipientCert, + _In_reads_(cRecipientCert) PCCERT_CONTEXT rgpRecipientCert[], + _In_reads_bytes_(cbToBeSignedAndEncrypted) const BYTE *pbToBeSignedAndEncrypted, + _In_ DWORD cbToBeSignedAndEncrypted, + _Out_writes_bytes_to_opt_(*pcbSignedAndEncryptedBlob, *pcbSignedAndEncryptedBlob) BYTE *pbSignedAndEncryptedBlob, + _Inout_ DWORD *pcbSignedAndEncryptedBlob); + +BOOL +WINAPI +CryptDecryptAndVerifyMessageSignature( + _In_ PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, + _In_ PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, + _In_ DWORD dwSignerIndex, + _In_reads_bytes_(cbEncryptedBlob) const BYTE *pbEncryptedBlob, + _In_ DWORD cbEncryptedBlob, + _Out_writes_bytes_to_opt_(*pcbDecrypted, *pcbDecrypted) BYTE *pbDecrypted, + _Inout_opt_ DWORD *pcbDecrypted, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppXchgCert, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppSignerCert); + +HCERTSTORE +WINAPI +CryptGetMessageCertificates( + _In_ DWORD dwMsgAndCertEncodingType, + _In_opt_ HCRYPTPROV_LEGACY hCryptProv, + _In_ DWORD dwFlags, + _In_reads_bytes_(cbSignedBlob) const BYTE *pbSignedBlob, + _In_ DWORD cbSignedBlob); + +BOOL +WINAPI +CryptDecodeMessage( + _In_ DWORD dwMsgTypeFlags, + _In_opt_ PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, + _In_opt_ PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, + _In_ DWORD dwSignerIndex, + _In_reads_bytes_(cbEncodedBlob) const BYTE *pbEncodedBlob, + _In_ DWORD cbEncodedBlob, + _In_ DWORD dwPrevInnerContentType, + _Out_opt_ DWORD *pdwMsgType, + _Out_opt_ DWORD *pdwInnerContentType, + _Out_writes_bytes_to_opt_(*pcbDecoded, *pcbDecoded) BYTE *pbDecoded, + _Inout_opt_ DWORD *pcbDecoded, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppXchgCert, + _Outptr_opt_result_maybenull_ PCCERT_CONTEXT *ppSignerCert); + +BOOL +WINAPI +CryptHashMessage( + _In_ PCRYPT_HASH_MESSAGE_PARA pHashPara, + _In_ BOOL fDetachedHash, + _In_ DWORD cToBeHashed, + _In_reads_(cToBeHashed) const BYTE *rgpbToBeHashed[], + _In_reads_(cToBeHashed) DWORD rgcbToBeHashed[], + _Out_writes_bytes_to_opt_(*pcbHashedBlob, *pcbHashedBlob) BYTE *pbHashedBlob, + _Inout_opt_ DWORD *pcbHashedBlob, + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_opt_ DWORD *pcbComputedHash); + +BOOL +WINAPI +CryptVerifyMessageHash( + _In_ PCRYPT_HASH_MESSAGE_PARA pHashPara, + _In_reads_bytes_(cbHashedBlob) BYTE *pbHashedBlob, + _In_ DWORD cbHashedBlob, + _Out_writes_bytes_to_opt_(*pcbToBeHashed, *pcbToBeHashed) BYTE *pbToBeHashed, + _Inout_opt_ DWORD *pcbToBeHashed, + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_opt_ DWORD *pcbComputedHash); + +BOOL +WINAPI +CryptVerifyDetachedMessageHash( + _In_ PCRYPT_HASH_MESSAGE_PARA pHashPara, + _In_reads_bytes_(cbDetachedHashBlob) BYTE *pbDetachedHashBlob, + _In_ DWORD cbDetachedHashBlob, + _In_ DWORD cToBeHashed, + _In_reads_(cToBeHashed) const BYTE *rgpbToBeHashed[], + _In_reads_(cToBeHashed) DWORD rgcbToBeHashed[], + _Out_writes_bytes_to_opt_(*pcbComputedHash, *pcbComputedHash) BYTE *pbComputedHash, + _Inout_opt_ DWORD *pcbComputedHash); /* PFX functions */ -HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, - DWORD dwFlags); -BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX); -BOOL WINAPI PFXVerifyPassword(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, - DWORD dwFlags); -BOOL WINAPI PFXExportCertStoreEx(HCERTSTORE hStore, CRYPT_DATA_BLOB *pPFX, - LPCWSTR szPassword, void *pvReserved, DWORD dwFlags); -BOOL WINAPI PFXExportCertStore(HCERTSTORE hStore, CRYPT_DATA_BLOB *pPFX, - LPCWSTR szPassword, DWORD dwFlags); +HCERTSTORE +WINAPI +PFXImportCertStore( + _In_ CRYPT_DATA_BLOB *pPFX, + _In_ LPCWSTR szPassword, + _In_ DWORD dwFlags); + +BOOL WINAPI PFXIsPFXBlob(_In_ CRYPT_DATA_BLOB *pPFX); + +BOOL +WINAPI +PFXVerifyPassword( + _In_ CRYPT_DATA_BLOB *pPFX, + _In_ LPCWSTR szPassword, + _In_ DWORD dwFlags); + +BOOL +WINAPI +PFXExportCertStoreEx( + _In_ HCERTSTORE hStore, + _Inout_ CRYPT_DATA_BLOB* pPFX, + _In_ LPCWSTR szPassword, + _In_ void* pvPara, + _In_ DWORD dwFlags); + +BOOL +WINAPI +PFXExportCertStore( + _In_ HCERTSTORE hStore, + _Inout_ CRYPT_DATA_BLOB* pPFX, + _In_ LPCWSTR szPassword, + _In_ DWORD dwFlags); + BOOL WINAPI PFXVerifyPassword(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, DWORD dwFlags); /* cryptnet.dll functions */ -BOOL WINAPI CryptCancelAsyncRetrieval(HCRYPTASYNC hAsyncRetrieval); +BOOL WINAPI CryptCancelAsyncRetrieval(_In_opt_ HCRYPTASYNC hAsyncRetrieval); -BOOL WINAPI CryptGetObjectUrl(LPCSTR pszUrlOid, LPVOID pvPara, DWORD dwFlags, - PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray, PCRYPT_URL_INFO pUrlInfo, - DWORD *pcbUrlInfo, LPVOID pvReserved); +BOOL +WINAPI +CryptGetObjectUrl( + _In_ LPCSTR pszUrlOid, + _In_ LPVOID pvPara, + _In_ DWORD dwFlags, + _Out_writes_bytes_to_opt_(*pcbUrlArray, *pcbUrlArray) PCRYPT_URL_ARRAY pUrlArray, + _Inout_ DWORD* pcbUrlArray, + _Out_writes_bytes_to_opt_(*pcbUrlInfo, *pcbUrlInfo) PCRYPT_URL_INFO pUrlInfo, + _Inout_opt_ DWORD* pcbUrlInfo, + _Reserved_ LPVOID pvReserved); -BOOL WINAPI CryptGetTimeValidObject(LPCSTR pszTimeValidOid, void *pvPara, - PCCERT_CONTEXT pIssuer, LPFILETIME pftValidFor, DWORD dwFlags, DWORD dwTimeout, - void **ppvObject, PCRYPT_CREDENTIALS pCredentials, void *pvReserved); +_Success_(return != 0) +BOOL +WINAPI +CryptGetTimeValidObject( + _In_ LPCSTR pszTimeValidOid, + _In_ void *pvPara, + _In_ PCCERT_CONTEXT pIssuer, + _In_opt_ LPFILETIME pftValidFor, + _In_ DWORD dwFlags, + _In_ DWORD dwTimeout, + _Outptr_opt_ void **ppvObject, + _In_opt_ PCRYPT_CREDENTIALS pCredentials, + _Inout_opt_ void *pvReserved); -BOOL WINAPI CryptFlushTimeValidObject(LPCSTR pszFlushTimeValidOid, void *pvPara, - PCCERT_CONTEXT pIssuer, DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptFlushTimeValidObject( + _In_ LPCSTR pszFlushTimeValidOid, + _In_ void *pvPara, + _In_ PCCERT_CONTEXT pIssuer, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); -BOOL WINAPI CryptInstallCancelRetrieval(PFN_CRYPT_CANCEL_RETRIEVAL pfnCancel, - const void *pvArg, DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptInstallCancelRetrieval( + __callback PFN_CRYPT_CANCEL_RETRIEVAL pfnCancel, + _In_opt_ const void *pvArg, + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); -BOOL WINAPI CryptUninstallCancelRetrieval(DWORD dwFlags, void *pvReserved); +BOOL +WINAPI +CryptUninstallCancelRetrieval( + _In_ DWORD dwFlags, + _Reserved_ void *pvReserved); + +_Success_(return != 0) +BOOL +WINAPI +CryptRetrieveObjectByUrlA( + _In_ LPCSTR pszUrl, + _In_opt_ LPCSTR pszObjectOid, + _In_ DWORD dwRetrievalFlags, + _In_ DWORD dwTimeout, + _Outptr_ LPVOID* ppvObject, + _In_opt_ HCRYPTASYNC hAsyncRetrieve, + _In_opt_ PCRYPT_CREDENTIALS pCredentials, + _In_opt_ LPVOID pvVerify, + _Inout_opt_ PCRYPT_RETRIEVE_AUX_INFO pAuxInfo); + +_Success_(return != 0) +BOOL +WINAPI +CryptRetrieveObjectByUrlW( + _In_ LPCWSTR pszUrl, + _In_opt_ LPCSTR pszObjectOid, + _In_ DWORD dwRetrievalFlags, + _In_ DWORD dwTimeout, + _Outptr_ LPVOID* ppvObject, + _In_opt_ HCRYPTASYNC hAsyncRetrieve, + _In_opt_ PCRYPT_CREDENTIALS pCredentials, + _In_opt_ LPVOID pvVerify, + _Inout_opt_ PCRYPT_RETRIEVE_AUX_INFO pAuxInfo); -BOOL WINAPI CryptRetrieveObjectByUrlA(LPCSTR pszURL, LPCSTR pszObjectOid, - DWORD dwRetrievalFlags, DWORD dwTimeout, LPVOID *ppvObject, - HCRYPTASYNC hAsyncRetrieve, PCRYPT_CREDENTIALS pCredentials, LPVOID pvVerify, - PCRYPT_RETRIEVE_AUX_INFO pAuxInfo); -BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid, - DWORD dwRetrievalFlags, DWORD dwTimeout, LPVOID *ppvObject, - HCRYPTASYNC hAsyncRetrieve, PCRYPT_CREDENTIALS pCredentials, LPVOID pvVerify, - PCRYPT_RETRIEVE_AUX_INFO pAuxInfo); #define CryptRetrieveObjectByUrl WINELIB_NAME_AW(CryptRetrieveObjectByUrl) /* Not found in crypt32.dll but in softpub.dll */ -HRESULT WINAPI FindCertsByIssuer(PCERT_CHAIN pCertChains, DWORD *pcbCertChains, - DWORD *pcCertChains, BYTE* pbEncodedIssuerName, DWORD cbEncodedIssuerName, - LPCWSTR pwszPurpose, DWORD dwKeySpec); +HRESULT +WINAPI +FindCertsByIssuer( + _Out_writes_bytes_to_opt_(*pcbCertChains, *pcbCertChains) PCERT_CHAIN pCertChains, + _Inout_ DWORD *pcbCertChains, + _Out_ DWORD *pcCertChains, + _In_reads_bytes_opt_(cbEncodedIssuerName) BYTE* pbEncodedIssuerName, + _In_ DWORD cbEncodedIssuerName, + _In_opt_ LPCWSTR pwszPurpose, + _In_ DWORD dwKeySpec); #ifdef _MSC_VER #pragma warning(pop) diff --git a/include/psdk/wininet.h b/include/psdk/wininet.h index 51d98643ba9..a70ce9d646f 100644 --- a/include/psdk/wininet.h +++ b/include/psdk/wininet.h @@ -24,7 +24,7 @@ extern "C" { #endif #define INTERNETAPI -#define BOOLAPI INTERNETAPI BOOL WINAPI +#define BOOLAPI _Success_(return != 0) INTERNETAPI BOOL WINAPI typedef LPVOID HINTERNET; typedef HINTERNET * LPHINTERNET; @@ -387,32 +387,104 @@ typedef struct _INTERNET_DIAGNOSTIC_SOCKET_INFO #define IDSI_FLAG_PROXY 0x00000004 #define IDSI_FLAG_TUNNEL 0x00000008 -BOOLAPI InternetTimeFromSystemTimeA(CONST SYSTEMTIME *,DWORD ,LPSTR ,DWORD); -BOOLAPI InternetTimeFromSystemTimeW(CONST SYSTEMTIME *,DWORD ,LPWSTR ,DWORD); +BOOLAPI +InternetTimeFromSystemTimeA( + _In_ CONST SYSTEMTIME *pst, + _In_ DWORD dwRFC, + _Out_writes_bytes_(cbTime) LPSTR lpszTime, + _In_ DWORD cbTime); + +BOOLAPI +InternetTimeFromSystemTimeW( + _In_ CONST SYSTEMTIME *pst, + _In_ DWORD dwRFC, + _Out_writes_bytes_(cbTime) LPWSTR lpszTime, + _In_ DWORD cbTime); + #define InternetTimeFromSystemTime WINELIB_NAME_AW(InternetTimeFromSystemTime) #define INTERNET_RFC1123_FORMAT 0 #define INTERNET_RFC1123_BUFSIZE 30 -BOOLAPI InternetTimeToSystemTimeA(LPCSTR ,SYSTEMTIME *,DWORD); -BOOLAPI InternetTimeToSystemTimeW(LPCWSTR ,SYSTEMTIME *,DWORD); +BOOLAPI +InternetTimeToSystemTimeA( + _In_ LPCSTR, + _Out_ SYSTEMTIME *, + _Reserved_ DWORD); + +BOOLAPI +InternetTimeToSystemTimeW( + _In_ LPCWSTR, + _Out_ SYSTEMTIME *, + _Reserved_ DWORD); + #define InternetTimeToSystemTime WINELIB_NAME_AW(InternetTimeToSystemTime) -BOOLAPI InternetCrackUrlA(LPCSTR ,DWORD ,DWORD ,LPURL_COMPONENTSA); -BOOLAPI InternetCrackUrlW(LPCWSTR ,DWORD ,DWORD ,LPURL_COMPONENTSW); -#define InternetCrackUrl WINELIB_NAME_AW(InternetCrackUrl) +BOOLAPI +InternetCrackUrlA( + _In_reads_(dwUrlLength) LPCSTR lpszUrl, + _In_ DWORD dwUrlLength, + _In_ DWORD dwFlags, + _Inout_ LPURL_COMPONENTSA lpUrlComponents); + +BOOLAPI +InternetCrackUrlW( + _In_reads_(dwUrlLength) LPCWSTR lpszUrl, + _In_ DWORD dwUrlLength, + _In_ DWORD dwFlags, + _Inout_ LPURL_COMPONENTSW lpUrlComponents); + +#define InternetCrackUrl WINELIB_NAME_AW(InternetCrackUrl) + +BOOLAPI +InternetCreateUrlA( + _In_ LPURL_COMPONENTSA lpUrlComponents, + _In_ DWORD dwFlags, + _Out_writes_opt_(*lpdwUrlLength) LPSTR lpszUrl, + _Inout_ LPDWORD lpdwUrlLength); + +BOOLAPI +InternetCreateUrlW( + _In_ LPURL_COMPONENTSW lpUrlComponents, + _In_ DWORD dwFlags, + _Out_writes_opt_(*lpdwUrlLength) LPWSTR lpszUrl, + _Inout_ LPDWORD lpdwUrlLength); -BOOLAPI InternetCreateUrlA(LPURL_COMPONENTSA ,DWORD ,LPSTR ,LPDWORD); -BOOLAPI InternetCreateUrlW(LPURL_COMPONENTSW ,DWORD ,LPWSTR ,LPDWORD); #define InternetCreateUrl WINELIB_NAME_AW(InternetCreateUrl) -BOOLAPI InternetCanonicalizeUrlA(LPCSTR ,LPSTR ,LPDWORD ,DWORD); -BOOLAPI InternetCanonicalizeUrlW(LPCWSTR ,LPWSTR ,LPDWORD ,DWORD); -#define InternetCanonicalizeUrl WINELIB_NAME_AW(InternetCanonicalizeUrl) +BOOLAPI +InternetCanonicalizeUrlA( + _In_ LPCSTR lpszUrl, + _Out_writes_(*lpdwBufferLength) LPSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _In_ DWORD dwFlags); -BOOLAPI InternetCombineUrlA(LPCSTR ,LPCSTR ,LPSTR ,LPDWORD ,DWORD); -BOOLAPI InternetCombineUrlW(LPCWSTR ,LPCWSTR ,LPWSTR ,LPDWORD ,DWORD); -#define InternetCombineUrl WINELIB_NAME_AW(InternetCombineUrl) +BOOLAPI +InternetCanonicalizeUrlW( + _In_ LPCWSTR lpszUrl, + _Out_writes_(*lpdwBufferLength) LPWSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _In_ DWORD dwFlags); + +#define InternetCanonicalizeUrl WINELIB_NAME_AW(InternetCanonicalizeUrl) + +BOOLAPI +InternetCombineUrlA( + _In_ LPCSTR lpszBaseUrl, + _In_ LPCSTR lpszRelativeUrl, + _Out_writes_(*lpdwBufferLength) LPSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _In_ DWORD dwFlags); + +BOOLAPI +InternetCombineUrlW( + _In_ LPCWSTR lpszBaseUrl, + _In_ LPCWSTR lpszRelativeUrl, + _Out_writes_(*lpdwBufferLength) LPWSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _In_ DWORD dwFlags); + +#define InternetCombineUrl WINELIB_NAME_AW(InternetCombineUrl) #define ICU_ESCAPE 0x80000000 #define ICU_USERNAME 0x40000000 @@ -423,9 +495,27 @@ BOOLAPI InternetCombineUrlW(LPCWSTR ,LPCWSTR ,LPWSTR ,LPDWORD ,DWORD); #define ICU_BROWSER_MODE 0x02000000 #define ICU_ENCODE_PERCENT 0x00001000 -INTERNETAPI HINTERNET WINAPI InternetOpenA(LPCSTR ,DWORD ,LPCSTR ,LPCSTR ,DWORD); -INTERNETAPI HINTERNET WINAPI InternetOpenW(LPCWSTR ,DWORD ,LPCWSTR ,LPCWSTR ,DWORD); -#define InternetOpen WINELIB_NAME_AW(InternetOpen) +INTERNETAPI +HINTERNET +WINAPI +InternetOpenA( + _In_opt_ LPCSTR, + _In_ DWORD, + _In_opt_ LPCSTR, + _In_opt_ LPCSTR, + _In_ DWORD); + +INTERNETAPI +HINTERNET +WINAPI +InternetOpenW( + _In_opt_ LPCWSTR, + _In_ DWORD, + _In_opt_ LPCWSTR, + _In_opt_ LPCWSTR, + _In_ DWORD); + +#define InternetOpen WINELIB_NAME_AW(InternetOpen) #define INTERNET_OPEN_TYPE_PRECONFIG 0 #define INTERNET_OPEN_TYPE_DIRECT 1 @@ -435,13 +525,35 @@ INTERNETAPI HINTERNET WINAPI InternetOpenW(LPCWSTR ,DWORD ,LPCWSTR ,LPCWSTR ,DWO #define LOCAL_INTERNET_ACCESS INTERNET_OPEN_TYPE_DIRECT #define CERN_PROXY_INTERNET_ACCESS INTERNET_OPEN_TYPE_PROXY -BOOLAPI InternetCloseHandle(HINTERNET); +BOOLAPI InternetCloseHandle(_In_ HINTERNET); -INTERNETAPI HINTERNET WINAPI InternetConnectA(HINTERNET ,LPCSTR ,INTERNET_PORT , - LPCSTR ,LPCSTR ,DWORD ,DWORD ,DWORD_PTR ); -INTERNETAPI HINTERNET WINAPI InternetConnectW(HINTERNET ,LPCWSTR ,INTERNET_PORT , - LPCWSTR ,LPCWSTR ,DWORD ,DWORD ,DWORD_PTR ); -#define InternetConnect WINELIB_NAME_AW(InternetConnect) +INTERNETAPI +HINTERNET +WINAPI +InternetConnectA( + _In_ HINTERNET, + _In_ LPCSTR, + _In_ INTERNET_PORT, + _In_opt_ LPCSTR, + _In_opt_ LPCSTR, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +INTERNETAPI +HINTERNET +WINAPI +InternetConnectW( + _In_ HINTERNET, + _In_ LPCWSTR, + _In_ INTERNET_PORT, + _In_opt_ LPCWSTR, + _In_opt_ LPCWSTR, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define InternetConnect WINELIB_NAME_AW(InternetConnect) #define INTERNET_SERVICE_URL 0 #define INTERNET_SERVICE_FTP 1 @@ -459,41 +571,126 @@ INTERNETAPI HINTERNET WINAPI InternetConnectW(HINTERNET ,LPCWSTR ,INTERNET_PORT dwContext \ ) -INTERNETAPI HINTERNET WINAPI InternetOpenUrlA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI InternetOpenUrlW(HINTERNET ,LPCWSTR ,LPCWSTR ,DWORD ,DWORD ,DWORD_PTR); -#define InternetOpenUrl WINELIB_NAME_AW(InternetOpenUrl) +INTERNETAPI +HINTERNET +WINAPI +InternetOpenUrlA( + _In_ HINTERNET hInternet, + _In_ LPCSTR lpszUrl, + _In_reads_opt_(dwHeadersLength) LPCSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); -BOOLAPI InternetReadFile( HINTERNET ,LPVOID ,DWORD ,LPDWORD ); -INTERNETAPI BOOL WINAPI InternetReadFileExA( HINTERNET ,LPINTERNET_BUFFERSA ,DWORD ,DWORD_PTR ); -INTERNETAPI BOOL WINAPI InternetReadFileExW( HINTERNET ,LPINTERNET_BUFFERSW ,DWORD ,DWORD_PTR ); -#define InternetReadFileEx WINELIB_NAME_AW(InternetReadFileEx) +INTERNETAPI +HINTERNET +WINAPI +InternetOpenUrlW( + _In_ HINTERNET hInternet, + _In_ LPCWSTR lpszUrl, + _In_reads_opt_(dwHeadersLength) LPCWSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +#define InternetOpenUrl WINELIB_NAME_AW(InternetOpenUrl) + +BOOLAPI +InternetReadFile( + _In_ HINTERNET hFile, + _Out_writes_bytes_(dwNumberOfBytesToRead) __out_data_source(NETWORK) LPVOID lpBuffer, + _In_ DWORD dwNumberOfBytesToRead, + _Out_ LPDWORD lpdwNumberOfBytesRead); + +BOOLAPI +InternetReadFileExA( + _In_ HINTERNET hFile, + _Out_ __out_data_source(NETWORK) LPINTERNET_BUFFERSA lpBuffersOut, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +BOOLAPI +InternetReadFileExW( + _In_ HINTERNET hFile, + _Out_ __out_data_source(NETWORK) LPINTERNET_BUFFERSW lpBuffersOut, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +#define InternetReadFileEx WINELIB_NAME_AW(InternetReadFileEx) #define IRF_ASYNC WININET_API_FLAG_ASYNC #define IRF_SYNC WININET_API_FLAG_SYNC #define IRF_USE_CONTEXT WININET_API_FLAG_USE_CONTEXT #define IRF_NO_WAIT 0x00000008 -INTERNETAPI DWORD WINAPI InternetSetFilePointer(HINTERNET ,LONG ,PVOID ,DWORD ,DWORD_PTR); -BOOLAPI InternetWriteFile(HINTERNET ,LPCVOID ,DWORD ,LPDWORD); -BOOLAPI InternetQueryDataAvailable(HINTERNET ,LPDWORD ,DWORD ,DWORD_PTR); -BOOLAPI InternetFindNextFileA(HINTERNET ,LPVOID); -BOOLAPI InternetFindNextFileW(HINTERNET ,LPVOID); +INTERNETAPI +DWORD +WINAPI +InternetSetFilePointer( + _In_ HINTERNET, + _In_ LONG, + _Inout_opt_ PVOID, + _In_ DWORD, + _Reserved_ DWORD_PTR); + +BOOLAPI +InternetWriteFile( + _In_ HINTERNET hFile, + _In_reads_bytes_(dwNumberOfBytesToWrite) LPCVOID lpBuffer, + _In_ DWORD dwNumberOfBytesToWrite, + _Out_ LPDWORD lpdwNumberOfBytesWritten); + +BOOLAPI +InternetQueryDataAvailable( + _In_ HINTERNET hFile, + _Out_opt_ __out_data_source(NETWORK) LPDWORD lpdwNumberOfBytesAvailable, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +BOOLAPI InternetFindNextFileA(_In_ HINTERNET, _Out_ LPVOID); +BOOLAPI InternetFindNextFileW(_In_ HINTERNET, _Out_ LPVOID); #define InternetFindNextFile WINELIB_NAME_AW(InternetFindNextFile) -BOOLAPI InternetQueryOptionA(HINTERNET ,DWORD ,LPVOID ,LPDWORD); -BOOLAPI InternetQueryOptionW(HINTERNET ,DWORD ,LPVOID ,LPDWORD); -#define InternetQueryOption WINELIB_NAME_AW(InternetQueryOption) +BOOLAPI +InternetQueryOptionA( + _In_opt_ HINTERNET hInternet, + _In_ DWORD dwOption, + _Out_writes_bytes_to_opt_(*lpdwBufferLength, *lpdwBufferLength) __out_data_source(NETWORK) LPVOID lpBuffer, + _Inout_ LPDWORD lpdwBufferLength); -BOOLAPI InternetSetOptionA(HINTERNET ,DWORD ,LPVOID ,DWORD); -BOOLAPI InternetSetOptionW(HINTERNET ,DWORD ,LPVOID ,DWORD); +BOOLAPI +InternetQueryOptionW( + _In_opt_ HINTERNET hInternet, + _In_ DWORD dwOption, + _Out_writes_bytes_to_opt_(*lpdwBufferLength, *lpdwBufferLength) __out_data_source(NETWORK) LPVOID lpBuffer, + _Inout_ LPDWORD lpdwBufferLength); + +#define InternetQueryOption WINELIB_NAME_AW(InternetQueryOption) + +BOOLAPI InternetSetOptionA(_In_opt_ HINTERNET, _In_ DWORD, _In_opt_ LPVOID, _In_ DWORD); +BOOLAPI InternetSetOptionW(_In_opt_ HINTERNET, _In_ DWORD, _In_opt_ LPVOID, _In_ DWORD); #define InternetSetOption WINELIB_NAME_AW(InternetSetOption) -BOOLAPI InternetSetOptionExA(HINTERNET ,DWORD ,LPVOID ,DWORD ,DWORD); -BOOLAPI InternetSetOptionExW(HINTERNET ,DWORD ,LPVOID ,DWORD ,DWORD); -#define InternetSetOptionEx WINELIB_NAME_AW(InternetSetOptionEx) +BOOLAPI +InternetSetOptionExA( + _In_opt_ HINTERNET, + _In_ DWORD, + _In_opt_ LPVOID, + _In_ DWORD, + _In_ DWORD); -BOOLAPI InternetLockRequestFile(HINTERNET ,HANDLE *); -BOOLAPI InternetUnlockRequestFile(HANDLE); +BOOLAPI +InternetSetOptionExW( + _In_opt_ HINTERNET, + _In_ DWORD, + _In_opt_ LPVOID, + _In_ DWORD, + _In_ DWORD); + +#define InternetSetOptionEx WINELIB_NAME_AW(InternetSetOptionEx) + +BOOLAPI InternetLockRequestFile(_In_ HINTERNET, _Out_ HANDLE *); +BOOLAPI InternetUnlockRequestFile(_Inout_ HANDLE); #define ISO_GLOBAL 0x00000001 #define ISO_REGISTRY 0x00000002 @@ -643,17 +840,43 @@ BOOLAPI InternetUnlockRequestFile(HANDLE); -BOOLAPI InternetGetLastResponseInfoA(LPDWORD ,LPSTR ,LPDWORD); -BOOLAPI InternetGetLastResponseInfoW(LPDWORD ,LPWSTR ,LPDWORD); -#define InternetGetLastResponseInfo WINELIB_NAME_AW(InternetGetLastResponseInfo) +BOOLAPI +InternetGetLastResponseInfoA( + _Out_ LPDWORD lpdwError, + _Out_writes_opt_(*lpdwBufferLength) LPSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength); -typedef VOID (CALLBACK *INTERNET_STATUS_CALLBACK)(HINTERNET ,DWORD_PTR ,DWORD , - LPVOID ,DWORD); +BOOLAPI +InternetGetLastResponseInfoW( + _Out_ LPDWORD lpdwError, + _Out_writes_opt_(*lpdwBufferLength) LPWSTR lpszBuffer, + _Inout_ LPDWORD lpdwBufferLength); +#define InternetGetLastResponseInfo WINELIB_NAME_AW(InternetGetLastResponseInfo) + +typedef VOID +(CALLBACK *INTERNET_STATUS_CALLBACK)( + _In_ HINTERNET, + _In_opt_ DWORD_PTR, + _In_ DWORD, + _In_opt_ LPVOID, + _In_ DWORD); typedef INTERNET_STATUS_CALLBACK * LPINTERNET_STATUS_CALLBACK; -INTERNETAPI INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackA(HINTERNET ,INTERNET_STATUS_CALLBACK); -INTERNETAPI INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW(HINTERNET ,INTERNET_STATUS_CALLBACK); +INTERNETAPI +INTERNET_STATUS_CALLBACK +WINAPI +InternetSetStatusCallbackA( + _In_ HINTERNET, + _In_opt_ INTERNET_STATUS_CALLBACK); + +INTERNETAPI +INTERNET_STATUS_CALLBACK +WINAPI +InternetSetStatusCallbackW( + _In_ HINTERNET, + _In_opt_ INTERNET_STATUS_CALLBACK); + #define InternetSetStatusCallback WINELIB_NAME_AW(InternetSetStatusCallback) #define INTERNET_STATUS_RESOLVING_NAME 10 @@ -695,53 +918,145 @@ INTERNETAPI INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW(HINTERNET #define FTP_TRANSFER_TYPE_BINARY 0x00000002 #define FTP_TRANSFER_TYPE_MASK (FTP_TRANSFER_TYPE_ASCII | FTP_TRANSFER_TYPE_BINARY) -BOOLAPI FtpCommandA(HINTERNET, BOOL, DWORD, LPCSTR, DWORD_PTR, HINTERNET *); -BOOLAPI FtpCommandW(HINTERNET, BOOL, DWORD, LPCWSTR, DWORD_PTR, HINTERNET *); -#define FtpCommand WINELIB_NAME_AW(FtpCommand) +BOOLAPI +FtpCommandA( + _In_ HINTERNET, + _In_ BOOL, + _In_ DWORD, + _In_ LPCSTR, + _In_opt_ DWORD_PTR, + _Out_opt_ HINTERNET *); -INTERNETAPI HINTERNET WINAPI FtpFindFirstFileA(HINTERNET ,LPCSTR , - LPWIN32_FIND_DATAA ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI FtpFindFirstFileW(HINTERNET ,LPCWSTR , - LPWIN32_FIND_DATAW ,DWORD ,DWORD_PTR); -#define FtpFindFirstFile WINELIB_NAME_AW(FtpFindFirstFile) +BOOLAPI +FtpCommandW( + _In_ HINTERNET, + _In_ BOOL, + _In_ DWORD, + _In_ LPCWSTR, + _In_opt_ DWORD_PTR, + _Out_opt_ HINTERNET *); -BOOLAPI FtpGetFileA(HINTERNET ,LPCSTR ,LPCSTR ,BOOL ,DWORD ,DWORD ,DWORD_PTR); -BOOLAPI FtpGetFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,BOOL ,DWORD ,DWORD ,DWORD_PTR); -#define FtpGetFile WINELIB_NAME_AW(FtpGetFile) +#define FtpCommand WINELIB_NAME_AW(FtpCommand) -DWORD WINAPI FtpGetFileSize(HINTERNET, LPDWORD); +INTERNETAPI +HINTERNET +WINAPI +FtpFindFirstFileA( + _In_ HINTERNET, + _In_opt_ LPCSTR, + _Out_opt_ LPWIN32_FIND_DATAA, + _In_ DWORD, + _In_opt_ DWORD_PTR); -BOOLAPI FtpPutFileA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD_PTR); -BOOLAPI FtpPutFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,DWORD ,DWORD_PTR); -#define FtpPutFile WINELIB_NAME_AW(FtpPutFile) +INTERNETAPI +HINTERNET +WINAPI +FtpFindFirstFileW( + _In_ HINTERNET, + _In_opt_ LPCWSTR, + _Out_opt_ LPWIN32_FIND_DATAW, + _In_ DWORD, + _In_opt_ DWORD_PTR); -BOOLAPI FtpDeleteFileA(HINTERNET ,LPCSTR); -BOOLAPI FtpDeleteFileW(HINTERNET ,LPCWSTR); +#define FtpFindFirstFile WINELIB_NAME_AW(FtpFindFirstFile) + +BOOLAPI +FtpGetFileA( + _In_ HINTERNET, + _In_ LPCSTR, + _In_ LPCSTR, + _In_ BOOL, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +BOOLAPI +FtpGetFileW( + _In_ HINTERNET, + _In_ LPCWSTR, + _In_ LPCWSTR, + _In_ BOOL, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define FtpGetFile WINELIB_NAME_AW(FtpGetFile) + +DWORD WINAPI FtpGetFileSize(_In_ HINTERNET, _Out_opt_ LPDWORD); + +BOOLAPI +FtpPutFileA( + _In_ HINTERNET, + _In_ LPCSTR, + _In_ LPCSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +BOOLAPI +FtpPutFileW( + _In_ HINTERNET, + _In_ LPCWSTR, + _In_ LPCWSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define FtpPutFile WINELIB_NAME_AW(FtpPutFile) + +BOOLAPI FtpDeleteFileA(_In_ HINTERNET, _In_ LPCSTR); +BOOLAPI FtpDeleteFileW(_In_ HINTERNET, _In_ LPCWSTR); #define FtpDeleteFile WINELIB_NAME_AW(FtpDeleteFile) -BOOLAPI FtpRenameFileA(HINTERNET ,LPCSTR ,LPCSTR); -BOOLAPI FtpRenameFileW(HINTERNET ,LPCWSTR ,LPCWSTR); +BOOLAPI FtpRenameFileA(_In_ HINTERNET, _In_ LPCSTR, _In_ LPCSTR); +BOOLAPI FtpRenameFileW(_In_ HINTERNET, _In_ LPCWSTR, _In_ LPCWSTR); #define FtpRenameFile WINELIB_NAME_AW(FtpRenameFile) -INTERNETAPI HINTERNET WINAPI FtpOpenFileA(HINTERNET ,LPCSTR ,DWORD ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI FtpOpenFileW(HINTERNET ,LPCWSTR ,DWORD ,DWORD ,DWORD_PTR); -#define FtpOpenFile WINELIB_NAME_AW(FtpOpenFile) +INTERNETAPI +HINTERNET +WINAPI +FtpOpenFileA( + _In_ HINTERNET, + _In_ LPCSTR, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); -BOOLAPI FtpCreateDirectoryA(HINTERNET ,LPCSTR); -BOOLAPI FtpCreateDirectoryW(HINTERNET ,LPCWSTR); +INTERNETAPI +HINTERNET +WINAPI +FtpOpenFileW( + _In_ HINTERNET, + _In_ LPCWSTR, + _In_ DWORD, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define FtpOpenFile WINELIB_NAME_AW(FtpOpenFile) + +BOOLAPI FtpCreateDirectoryA(_In_ HINTERNET, _In_ LPCSTR); +BOOLAPI FtpCreateDirectoryW(_In_ HINTERNET, _In_ LPCWSTR); #define FtpCreateDirectory WINELIB_NAME_AW(FtpCreateDirectory) -BOOLAPI FtpRemoveDirectoryA(HINTERNET ,LPCSTR); -BOOLAPI FtpRemoveDirectoryW(HINTERNET ,LPCWSTR); +BOOLAPI FtpRemoveDirectoryA(_In_ HINTERNET, _In_ LPCSTR); +BOOLAPI FtpRemoveDirectoryW(_In_ HINTERNET, _In_ LPCWSTR); #define FtpRemoveDirectory WINELIB_NAME_AW(FtpRemoveDirectory) -BOOLAPI FtpSetCurrentDirectoryA(HINTERNET ,LPCSTR); -BOOLAPI FtpSetCurrentDirectoryW(HINTERNET ,LPCWSTR); +BOOLAPI FtpSetCurrentDirectoryA(_In_ HINTERNET, _In_ LPCSTR); +BOOLAPI FtpSetCurrentDirectoryW(_In_ HINTERNET, _In_ LPCWSTR); #define FtpSetCurrentDirectory WINELIB_NAME_AW(FtpSetCurrentDirectory) -BOOLAPI FtpGetCurrentDirectoryA(HINTERNET ,LPSTR ,LPDWORD); -BOOLAPI FtpGetCurrentDirectoryW(HINTERNET ,LPWSTR ,LPDWORD); -#define FtpGetCurrentDirectory WINELIB_NAME_AW(FtpGetCurrentDirectory) +BOOLAPI +FtpGetCurrentDirectoryA( + _In_ HINTERNET hConnect, + _Out_writes_(*lpdwCurrentDirectory) LPSTR lpszCurrentDirectory, + _Inout_ LPDWORD lpdwCurrentDirectory); + +BOOLAPI +FtpGetCurrentDirectoryW( + _In_ HINTERNET hConnect, + _Out_writes_(*lpdwCurrentDirectory) LPWSTR lpszCurrentDirectory, + _Inout_ LPDWORD lpdwCurrentDirectory); + +#define FtpGetCurrentDirectory WINELIB_NAME_AW(FtpGetCurrentDirectory) #define MAX_GOPHER_DISPLAY_TEXT 128 #define MAX_GOPHER_SELECTOR_TEXT 256 @@ -1093,36 +1408,113 @@ DECL_WINELIB_TYPE_AW(LPGOPHER_ATTRIBUTE_TYPE) #define GOPHER_ATTRIBUTE_ID_TREEWALK (GOPHER_ATTRIBUTE_ID_BASE + 24) #define GOPHER_ATTRIBUTE_ID_UNKNOWN (GOPHER_ATTRIBUTE_ID_BASE + 25) -BOOLAPI GopherCreateLocatorA(LPCSTR ,INTERNET_PORT ,LPCSTR , - LPCSTR ,DWORD ,LPSTR ,LPDWORD); -BOOLAPI GopherCreateLocatorW(LPCWSTR ,INTERNET_PORT ,LPCWSTR , - LPCWSTR ,DWORD ,LPWSTR ,LPDWORD); -#define GopherCreateLocator WINELIB_NAME_AW(GopherCreateLocator) +BOOLAPI +GopherCreateLocatorA( + _In_ LPCSTR lpszHost, + _In_ INTERNET_PORT nServerPort, + _In_opt_ LPCSTR lpszDisplayString, + _In_opt_ LPCSTR lpszSelectorString, + _In_ DWORD dwGopherType, + _Out_writes_opt_(*lpdwBufferLength) LPSTR lpszLocator, + _Inout_ LPDWORD lpdwBufferLength); -BOOLAPI GopherGetLocatorTypeA(LPCSTR ,LPDWORD); -BOOLAPI GopherGetLocatorTypeW(LPCWSTR ,LPDWORD); -#define GopherGetLocatorType WINELIB_NAME_AW(GopherGetLocatorType) +BOOLAPI +GopherCreateLocatorW( + _In_ LPCWSTR lpszHost, + _In_ INTERNET_PORT nServerPort, + _In_opt_ LPCWSTR lpszDisplayString, + _In_opt_ LPCWSTR lpszSelectorString, + _In_ DWORD dwGopherType, + _Out_writes_opt_(*lpdwBufferLength) LPWSTR lpszLocator, + _Inout_ LPDWORD lpdwBufferLength); -INTERNETAPI HINTERNET WINAPI GopherFindFirstFileA(HINTERNET ,LPCSTR , - LPCSTR ,LPGOPHER_FIND_DATAA ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI GopherFindFirstFileW(HINTERNET ,LPCWSTR , - LPCWSTR ,LPGOPHER_FIND_DATAW ,DWORD ,DWORD_PTR); -#define GopherFindFirstFile WINELIB_NAME_AW(GopherFindFirstFile) +#define GopherCreateLocator WINELIB_NAME_AW(GopherCreateLocator) -INTERNETAPI HINTERNET WINAPI GopherOpenFileA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI GopherOpenFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,DWORD ,DWORD_PTR); -#define GopherOpenFile WINELIB_NAME_AW(GopherOpenFile) +BOOLAPI GopherGetLocatorTypeA(_In_ LPCSTR, _Out_ LPDWORD); +BOOLAPI GopherGetLocatorTypeW(_In_ LPCWSTR, _Out_ LPDWORD); +#define GopherGetLocatorType WINELIB_NAME_AW(GopherGetLocatorType) -typedef BOOL (CALLBACK *GOPHER_ATTRIBUTE_ENUMERATORA)(LPGOPHER_ATTRIBUTE_TYPEA ,DWORD); -typedef BOOL (CALLBACK *GOPHER_ATTRIBUTE_ENUMERATORW)(LPGOPHER_ATTRIBUTE_TYPEW ,DWORD); +INTERNETAPI +HINTERNET +WINAPI +GopherFindFirstFileA( + _In_ HINTERNET hConnect, + _In_opt_ LPCSTR lpszLocator, + _In_opt_ LPCSTR lpszSearchString, + _Out_opt_ LPGOPHER_FIND_DATAA lpFindData, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +INTERNETAPI +HINTERNET +WINAPI +GopherFindFirstFileW( + _In_ HINTERNET hConnect, + _In_opt_ LPCWSTR lpszLocator, + _In_opt_ LPCWSTR lpszSearchString, + _Out_opt_ LPGOPHER_FIND_DATAW lpFindData, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +#define GopherFindFirstFile WINELIB_NAME_AW(GopherFindFirstFile) + +INTERNETAPI +HINTERNET +WINAPI +GopherOpenFileA( + _In_ HINTERNET, + _In_ LPCSTR, + _In_opt_ LPCSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +INTERNETAPI +HINTERNET +WINAPI +GopherOpenFileW( + _In_ HINTERNET, + _In_ LPCWSTR, + _In_opt_ LPCWSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define GopherOpenFile WINELIB_NAME_AW(GopherOpenFile) + +typedef BOOL +(CALLBACK *GOPHER_ATTRIBUTE_ENUMERATORA)( + _In_ LPGOPHER_ATTRIBUTE_TYPEA, + _In_ DWORD); + +typedef BOOL +(CALLBACK *GOPHER_ATTRIBUTE_ENUMERATORW)( + _In_ LPGOPHER_ATTRIBUTE_TYPEW, + _In_ DWORD); DECL_WINELIB_TYPE_AW(GOPHER_ATTRIBUTE_ENUMERATOR) -BOOLAPI GopherGetAttributeA(HINTERNET ,LPCSTR ,LPCSTR ,LPBYTE , - DWORD ,LPDWORD ,GOPHER_ATTRIBUTE_ENUMERATORA ,DWORD_PTR); -BOOLAPI GopherGetAttributeW(HINTERNET ,LPCWSTR ,LPCWSTR ,LPBYTE , - DWORD ,LPDWORD ,GOPHER_ATTRIBUTE_ENUMERATORW ,DWORD_PTR); -#define GopherGetAttribute WINELIB_NAME_AW(GopherGetAttribute) +BOOLAPI +GopherGetAttributeA( + _In_ HINTERNET hConnect, + _In_ LPCSTR lpszLocator, + _In_opt_ LPCSTR lpszAttributeName, + _At_((LPSTR) lpBuffer, _Out_writes_(dwBufferLength)) LPBYTE lpBuffer, + _In_ DWORD dwBufferLength, + _Out_ LPDWORD lpdwCharactersReturned, + _In_opt_ GOPHER_ATTRIBUTE_ENUMERATORA lpfnEnumerator, + _In_opt_ DWORD_PTR dwContext); + +BOOLAPI +GopherGetAttributeW( + _In_ HINTERNET hConnect, + _In_ LPCWSTR lpszLocator, + _In_opt_ LPCWSTR lpszAttributeName, + _At_((LPWSTR) lpBuffer, _Out_writes_(dwBufferLength)) LPBYTE lpBuffer, + _In_ DWORD dwBufferLength, + _Out_ LPDWORD lpdwCharactersReturned, + _In_opt_ GOPHER_ATTRIBUTE_ENUMERATORW lpfnEnumerator, + _In_opt_ DWORD_PTR dwContext); + +#define GopherGetAttribute WINELIB_NAME_AW(GopherGetAttribute) #define HTTP_MAJOR_VERSION 1 #define HTTP_MINOR_VERSION 0 @@ -1261,15 +1653,52 @@ BOOLAPI GopherGetAttributeW(HINTERNET ,LPCWSTR ,LPCWSTR ,LPBYTE , #define HTTP_STATUS_LAST HTTP_STATUS_VERSION_NOT_SUP -INTERNETAPI HINTERNET WINAPI HttpOpenRequestA(HINTERNET ,LPCSTR ,LPCSTR ,LPCSTR , - LPCSTR ,LPCSTR * ,DWORD ,DWORD_PTR); -INTERNETAPI HINTERNET WINAPI HttpOpenRequestW(HINTERNET ,LPCWSTR ,LPCWSTR ,LPCWSTR , - LPCWSTR ,LPCWSTR * ,DWORD ,DWORD_PTR); -#define HttpOpenRequest WINELIB_NAME_AW(HttpOpenRequest) +INTERNETAPI +HINTERNET +WINAPI +HttpOpenRequestA( + _In_ HINTERNET hConnect, + _In_opt_ LPCSTR lpszVerb, + _In_opt_ LPCSTR lpszObjectName, + _In_opt_ LPCSTR lpszVersion, + _In_opt_ LPCSTR lpszReferrer, + _In_opt_z_ LPCSTR FAR * lplpszAcceptTypes, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); -BOOLAPI HttpAddRequestHeadersA(HINTERNET ,LPCSTR ,DWORD ,DWORD); -BOOLAPI HttpAddRequestHeadersW(HINTERNET ,LPCWSTR ,DWORD ,DWORD); -#define HttpAddRequestHeaders WINELIB_NAME_AW(HttpAddRequestHeaders) +INTERNETAPI +HINTERNET +WINAPI HttpOpenRequestW( + _In_ HINTERNET hConnect, + _In_opt_ LPCWSTR lpszVerb, + _In_opt_ LPCWSTR lpszObjectName, + _In_opt_ LPCWSTR lpszVersion, + _In_opt_ LPCWSTR lpszReferrer, + _In_opt_z_ LPCWSTR FAR * lplpszAcceptTypes, + _In_ DWORD dwFlags, + _In_opt_ DWORD_PTR dwContext); + +#define HttpOpenRequest WINELIB_NAME_AW(HttpOpenRequest) + +BOOLAPI +HttpAddRequestHeadersA( + _In_ HINTERNET hRequest, + _When_(dwHeadersLength == (DWORD) - 1, _In_z_) + _When_(dwHeadersLength != (DWORD) - 1, _In_reads_(dwHeadersLength)) + LPCSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_ DWORD dwModifiers); + +BOOLAPI +HttpAddRequestHeadersW( + _In_ HINTERNET hRequest, + _When_(dwHeadersLength == (DWORD) - 1, _In_z_) + _When_(dwHeadersLength != (DWORD) - 1, _In_reads_(dwHeadersLength)) + LPCWSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_ DWORD dwModifiers); + +#define HttpAddRequestHeaders WINELIB_NAME_AW(HttpAddRequestHeaders) #define HTTP_ADDREQ_INDEX_MASK 0x0000FFFF #define HTTP_ADDREQ_FLAGS_MASK 0xFFFF0000 @@ -1280,15 +1709,41 @@ BOOLAPI HttpAddRequestHeadersW(HINTERNET ,LPCWSTR ,DWORD ,DWORD); #define HTTP_ADDREQ_FLAG_COALESCE HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA #define HTTP_ADDREQ_FLAG_REPLACE 0x80000000 -BOOLAPI HttpSendRequestA(HINTERNET ,LPCSTR ,DWORD ,LPVOID ,DWORD); -BOOLAPI HttpSendRequestW(HINTERNET ,LPCWSTR ,DWORD ,LPVOID ,DWORD); -#define HttpSendRequest WINELIB_NAME_AW(HttpSendRequest) +BOOLAPI +HttpSendRequestA( + _In_ HINTERNET hRequest, + _In_reads_opt_(dwHeadersLength) LPCSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_reads_bytes_opt_(dwOptionalLength) LPVOID lpOptional, + _In_ DWORD dwOptionalLength); -INTERNETAPI BOOL WINAPI HttpSendRequestExA(HINTERNET ,LPINTERNET_BUFFERSA , - LPINTERNET_BUFFERSA ,DWORD ,DWORD_PTR); -INTERNETAPI BOOL WINAPI HttpSendRequestExW(HINTERNET ,LPINTERNET_BUFFERSW , - LPINTERNET_BUFFERSW ,DWORD ,DWORD_PTR); -#define HttpSendRequestEx WINELIB_NAME_AW(HttpSendRequestEx) +BOOLAPI +HttpSendRequestW( + _In_ HINTERNET hRequest, + _In_reads_opt_(dwHeadersLength) LPCWSTR lpszHeaders, + _In_ DWORD dwHeadersLength, + _In_reads_bytes_opt_(dwOptionalLength) LPVOID lpOptional, + _In_ DWORD dwOptionalLength); + +#define HttpSendRequest WINELIB_NAME_AW(HttpSendRequest) + +BOOLAPI +HttpSendRequestExA( + _In_ HINTERNET, + _In_opt_ LPINTERNET_BUFFERSA, + _Out_opt_ LPINTERNET_BUFFERSA, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +BOOLAPI +HttpSendRequestExW( + _In_ HINTERNET, + _In_opt_ LPINTERNET_BUFFERSW, + _Out_opt_ LPINTERNET_BUFFERSW, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define HttpSendRequestEx WINELIB_NAME_AW(HttpSendRequestEx) #define HSR_ASYNC WININET_API_FLAG_ASYNC #define HSR_SYNC WININET_API_FLAG_SYNC @@ -1297,18 +1752,56 @@ INTERNETAPI BOOL WINAPI HttpSendRequestExW(HINTERNET ,LPINTERNET_BUFFERSW , #define HSR_DOWNLOAD 0x00000010 #define HSR_CHUNKED 0x00000020 -INTERNETAPI BOOL WINAPI HttpEndRequestA(HINTERNET ,LPINTERNET_BUFFERSA ,DWORD ,DWORD_PTR); -INTERNETAPI BOOL WINAPI HttpEndRequestW(HINTERNET ,LPINTERNET_BUFFERSW ,DWORD ,DWORD_PTR); -#define HttpEndRequest WINELIB_NAME_AW(HttpEndRequest) +BOOLAPI +HttpEndRequestA( + _In_ HINTERNET, + _Out_opt_ LPINTERNET_BUFFERSA, + _In_ DWORD, + _In_opt_ DWORD_PTR); -BOOLAPI HttpQueryInfoA(HINTERNET ,DWORD ,LPVOID ,LPDWORD ,LPDWORD); -BOOLAPI HttpQueryInfoW(HINTERNET ,DWORD ,LPVOID ,LPDWORD ,LPDWORD); -#define HttpQueryInfo WINELIB_NAME_AW(HttpQueryInfo) +BOOLAPI +HttpEndRequestW( + _In_ HINTERNET, + _Out_opt_ LPINTERNET_BUFFERSW, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +#define HttpEndRequest WINELIB_NAME_AW(HttpEndRequest) + +BOOLAPI +HttpQueryInfoA( + _In_ HINTERNET hRequest, + _In_ DWORD dwInfoLevel, + _Inout_updates_bytes_to_opt_(*lpdwBufferLength, *lpdwBufferLength) __out_data_source(NETWORK) LPVOID lpBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _Inout_opt_ LPDWORD lpdwIndex); + +BOOLAPI +HttpQueryInfoW( + _In_ HINTERNET hRequest, + _In_ DWORD dwInfoLevel, + _Inout_updates_bytes_to_opt_(*lpdwBufferLength, *lpdwBufferLength) __out_data_source(NETWORK) LPVOID lpBuffer, + _Inout_ LPDWORD lpdwBufferLength, + _Inout_opt_ LPDWORD lpdwIndex); + +#define HttpQueryInfo WINELIB_NAME_AW(HttpQueryInfo) BOOLAPI InternetClearAllPerSiteCookieDecisions(VOID); -BOOLAPI InternetEnumPerSiteCookieDecisionA(LPSTR,ULONG *,ULONG *,ULONG); -BOOLAPI InternetEnumPerSiteCookieDecisionW(LPWSTR,ULONG *,ULONG *,ULONG); +BOOLAPI +InternetEnumPerSiteCookieDecisionA( + _Out_writes_to_(*pcSiteNameSize, *pcSiteNameSize) LPSTR pszSiteName, + _Inout_ ULONG *pcSiteNameSize, + _Out_ ULONG *pdwDecision, + _In_ ULONG dwIndex); + +BOOLAPI +InternetEnumPerSiteCookieDecisionW( + _Out_writes_to_(*pcSiteNameSize, *pcSiteNameSize) LPWSTR pszSiteName, + _Inout_ ULONG *pcSiteNameSize, + _Out_ ULONG *pdwDecision, + _In_ ULONG dwIndex); + #define InternetEnumPerSiteCookieDecision WINELIB_NAME_AW(InternetEnumPerSiteCookieDecision) #define INTERNET_COOKIE_IS_SECURE 0x00000001 @@ -1322,33 +1815,78 @@ BOOLAPI InternetEnumPerSiteCookieDecisionW(LPWSTR,ULONG *,ULONG *,ULONG); #define INTERNET_COOKIE_IE6 0x00000400 #define INTERNET_COOKIE_IS_LEGACY 0x00000800 -BOOLAPI InternetGetCookieExA(LPCSTR,LPCSTR,LPSTR,LPDWORD,DWORD,LPVOID); -BOOLAPI InternetGetCookieExW(LPCWSTR,LPCWSTR,LPWSTR,LPDWORD,DWORD,LPVOID); +BOOLAPI +InternetGetCookieExA( + _In_ LPCSTR lpszUrl, + _In_opt_ LPCSTR lpszCookieName, + _In_reads_opt_(*lpdwSize) LPSTR lpszCookieData, + _Inout_ LPDWORD lpdwSize, + _In_ DWORD dwFlags, + _Reserved_ LPVOID lpReserved); + +BOOLAPI +InternetGetCookieExW( + _In_ LPCWSTR lpszUrl, + _In_opt_ LPCWSTR lpszCookieName, + _In_reads_opt_(*lpdwSize) LPWSTR lpszCookieData, + _Inout_ LPDWORD lpdwSize, + _In_ DWORD dwFlags, + _Reserved_ LPVOID lpReserved); + #define InternetGetCookieEx WINELIB_NAME_AW(InternetGetCookieEx) -DWORD WINAPI InternetSetCookieExA(LPCSTR,LPCSTR,LPCSTR,DWORD,DWORD_PTR); -DWORD WINAPI InternetSetCookieExW(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,DWORD_PTR); +DWORD +WINAPI +InternetSetCookieExA( + _In_ LPCSTR, + _In_opt_ LPCSTR, + _In_ LPCSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + +DWORD +WINAPI +InternetSetCookieExW( + _In_ LPCWSTR, + _In_opt_ LPCWSTR, + _In_ LPCWSTR, + _In_ DWORD, + _In_opt_ DWORD_PTR); + #define InternetSetCookieEx WINELIB_NAME_AW(InternetSetCookieEx) -BOOLAPI InternetGetPerSiteCookieDecisionA(LPCSTR,ULONG *); -BOOLAPI InternetGetPerSiteCookieDecisionW(LPCWSTR,ULONG *); +BOOLAPI InternetGetPerSiteCookieDecisionA(_In_ LPCSTR, _Out_ ULONG *); +BOOLAPI InternetGetPerSiteCookieDecisionW(_In_ LPCWSTR, _Out_ ULONG *); #define InternetGetPerSiteCookieDecision WINELIB_NAME_AW(InternetGetPerSiteCookieDecision) -BOOLAPI InternetSetPerSiteCookieDecisionA(LPCSTR,DWORD); -BOOLAPI InternetSetPerSiteCookieDecisionW(LPCWSTR,DWORD); +BOOLAPI InternetSetPerSiteCookieDecisionA(_In_ LPCSTR, _In_ DWORD); +BOOLAPI InternetSetPerSiteCookieDecisionW(_In_ LPCWSTR, _In_ DWORD); #define InternetSetPerSiteCookieDecision WINELIB_NAME_AW(InternetSetPerSiteCookieDecision) -BOOLAPI InternetSetCookieA(LPCSTR ,LPCSTR ,LPCSTR); -BOOLAPI InternetSetCookieW(LPCWSTR ,LPCWSTR ,LPCWSTR); +BOOLAPI InternetSetCookieA(_In_ LPCSTR, _In_opt_ LPCSTR, _In_ LPCSTR); +BOOLAPI InternetSetCookieW(_In_ LPCWSTR, _In_opt_ LPCWSTR, _In_ LPCWSTR); #define InternetSetCookie WINELIB_NAME_AW(InternetSetCookie) -BOOLAPI InternetGetCookieA(LPCSTR ,LPCSTR ,LPSTR ,LPDWORD); -BOOLAPI InternetGetCookieW(LPCWSTR ,LPCWSTR ,LPWSTR ,LPDWORD); -#define InternetGetCookie WINELIB_NAME_AW(InternetGetCookie) +BOOLAPI +InternetGetCookieA( + _In_ LPCSTR lpszUrl, + _In_opt_ LPCSTR lpszCookieName, + _Out_writes_opt_(*lpdwSize) LPSTR lpszCookieData, + _Inout_ LPDWORD lpdwSize); -INTERNETAPI DWORD WINAPI InternetAttemptConnect(DWORD); -BOOLAPI InternetCheckConnectionA(LPCSTR ,DWORD ,DWORD); -BOOLAPI InternetCheckConnectionW(LPCWSTR ,DWORD ,DWORD); +BOOLAPI +InternetGetCookieW( + _In_ LPCWSTR lpszUrl, + _In_opt_ LPCWSTR lpszCookieName, + _Out_writes_opt_(*lpdwSize) LPWSTR lpszCookieData, + _Inout_ LPDWORD lpdwSize); + +#define InternetGetCookie WINELIB_NAME_AW(InternetGetCookie) + +INTERNETAPI DWORD WINAPI InternetAttemptConnect(_In_ DWORD); + +BOOLAPI InternetCheckConnectionA(_In_ LPCSTR, _In_ DWORD, _In_ DWORD); +BOOLAPI InternetCheckConnectionW(_In_ LPCWSTR, _In_ DWORD, _In_ DWORD); #define InternetCheckConnection WINELIB_NAME_AW(InternetCheckConnection) #define FLAG_ICC_FORCE_CONNECTION 0x00000001 @@ -1372,9 +1910,34 @@ typedef struct INTERNET_AUTH_NOTIFY_DATA; -INTERNETAPI DWORD WINAPI InternetErrorDlg(HWND ,HINTERNET ,DWORD ,DWORD ,LPVOID *); -INTERNETAPI DWORD WINAPI InternetConfirmZoneCrossingA(HWND ,LPSTR ,LPSTR ,BOOL); -INTERNETAPI DWORD WINAPI InternetConfirmZoneCrossingW(HWND ,LPWSTR ,LPWSTR ,BOOL); +INTERNETAPI +DWORD +WINAPI +InternetErrorDlg( + _In_ HWND, + _Inout_opt_ HINTERNET, + _In_ DWORD, + _In_ DWORD, + _Inout_opt_ LPVOID *); + +INTERNETAPI +DWORD +WINAPI +InternetConfirmZoneCrossingA( + _In_ HWND, + _In_ LPSTR, + _In_ LPSTR, + _In_ BOOL); + +INTERNETAPI +DWORD +WINAPI +InternetConfirmZoneCrossingW( + _In_ HWND, + _In_ LPWSTR, + _In_ LPWSTR, + _In_ BOOL); + #define InternetConfirmZoneCrossing WINELIB_NAME_AW(InternetConfirmZoneCrossing) #define PRIVACY_TEMPLATE_NO_COOKIES 0 @@ -1391,8 +1954,24 @@ INTERNETAPI DWORD WINAPI InternetConfirmZoneCrossingW(HWND ,LPWSTR ,LPWSTR ,BOOL #define PRIVACY_TYPE_FIRST_PARTY 0 #define PRIVACY_TYPE_THIRD_PARTY 1 -INTERNETAPI DWORD WINAPI PrivacySetZonePreferenceW(DWORD,DWORD,DWORD,LPCWSTR); -INTERNETAPI DWORD WINAPI PrivacyGetZonePreferenceW(DWORD,DWORD,LPDWORD,LPWSTR,LPDWORD); +INTERNETAPI +DWORD +WINAPI +PrivacySetZonePreferenceW( + _In_ DWORD, + _In_ DWORD, + _In_ DWORD, + _In_opt_ LPCWSTR); + +INTERNETAPI +DWORD +WINAPI +PrivacyGetZonePreferenceW( + _In_ DWORD dwZone, + _In_ DWORD dwType, + _Out_opt_ LPDWORD pdwTemplate, + _Out_writes_opt_(*pdwBufferLength) LPWSTR pszBuffer, + _Inout_opt_ LPDWORD pdwBufferLength); #define INTERNET_ERROR_BASE 12000 @@ -1564,41 +2143,139 @@ typedef struct _INTERNET_CACHE_TIMESTAMPS FILETIME ftLastModified; } INTERNET_CACHE_TIMESTAMPS, *LPINTERNET_CACHE_TIMESTAMPS; -BOOLAPI CreateUrlCacheEntryA(LPCSTR ,DWORD ,LPCSTR ,LPSTR ,DWORD); -BOOLAPI CreateUrlCacheEntryW(LPCWSTR ,DWORD ,LPCWSTR ,LPWSTR ,DWORD); -#define CreateUrlCacheEntry WINELIB_NAME_AW(CreateUrlCacheEntry) +BOOLAPI +CreateUrlCacheEntryA( + _In_ LPCSTR lpszUrlName, + _In_ DWORD dwExpectedFileSize, + _In_opt_ LPCSTR lpszFileExtension, + _Inout_updates_(MAX_PATH) LPSTR lpszFileName, + _In_ DWORD dwReserved); -BOOLAPI CommitUrlCacheEntryA(LPCSTR,LPCSTR,FILETIME,FILETIME,DWORD,LPBYTE,DWORD,LPCSTR,LPCSTR); -BOOLAPI CommitUrlCacheEntryW(LPCWSTR,LPCWSTR,FILETIME,FILETIME,DWORD,LPWSTR,DWORD,LPCWSTR,LPCWSTR); -#define CommitUrlCacheEntry WINELIB_NAME_AW(CommitUrlCacheEntry) +BOOLAPI +CreateUrlCacheEntryW( + _In_ LPCWSTR lpszUrlName, + _In_ DWORD dwExpectedFileSize, + _In_opt_ LPCWSTR lpszFileExtension, + _Inout_updates_(MAX_PATH) LPWSTR lpszFileName, + _In_ DWORD dwReserved); -BOOLAPI ResumeSuspendedDownload(HINTERNET, DWORD); +#define CreateUrlCacheEntry WINELIB_NAME_AW(CreateUrlCacheEntry) -BOOLAPI RetrieveUrlCacheEntryFileA(LPCSTR ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD ,DWORD); -BOOLAPI RetrieveUrlCacheEntryFileW(LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD ,DWORD); -#define RetrieveUrlCacheEntryFile WINELIB_NAME_AW(RetrieveUrlCacheEntryFile) +BOOLAPI +CommitUrlCacheEntryA( + _In_ LPCSTR lpszUrlName, + _In_opt_ LPCSTR lpszLocalFileName, + _In_ FILETIME ExpireTime, + _In_ FILETIME LastModifiedTime, + _In_ DWORD CacheEntryType, + _In_reads_opt_(cchHeaderInfo) LPBYTE lpHeaderInfo, + _In_ DWORD cchHeaderInfo, + _Reserved_ LPCSTR lpszFileExtension, + _In_opt_ LPCSTR lpszOriginalUrl); -BOOLAPI UnlockUrlCacheEntryFileA(LPCSTR ,DWORD); -BOOLAPI UnlockUrlCacheEntryFileW(LPCWSTR ,DWORD); +BOOLAPI +CommitUrlCacheEntryW( + _In_ LPCWSTR lpszUrlName, + _In_opt_ LPCWSTR lpszLocalFileName, + _In_ FILETIME ExpireTime, + _In_ FILETIME LastModifiedTime, + _In_ DWORD CacheEntryType, + _In_reads_opt_(cchHeaderInfo) LPWSTR lpszHeaderInfo, + _In_ DWORD cchHeaderInfo, + _Reserved_ LPCWSTR lpszFileExtension, + _In_opt_ LPCWSTR lpszOriginalUrl); + +#define CommitUrlCacheEntry WINELIB_NAME_AW(CommitUrlCacheEntry) + +BOOLAPI ResumeSuspendedDownload(_In_ HINTERNET, _In_ DWORD); + +BOOLAPI +RetrieveUrlCacheEntryFileA( + _In_ LPCSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ DWORD dwReserved); + +BOOLAPI +RetrieveUrlCacheEntryFileW( + _In_ LPCWSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ DWORD dwReserved); + +#define RetrieveUrlCacheEntryFile WINELIB_NAME_AW(RetrieveUrlCacheEntryFile) + +BOOLAPI UnlockUrlCacheEntryFileA(_In_ LPCSTR, _Reserved_ DWORD); +BOOLAPI UnlockUrlCacheEntryFileW(_In_ LPCWSTR, _Reserved_ DWORD); #define UnlockUrlCacheEntryFile WINELIB_NAME_AW(UnlockUrlCacheEntryFile) -INTERNETAPI HANDLE WINAPI RetrieveUrlCacheEntryStreamA(LPCSTR , - LPINTERNET_CACHE_ENTRY_INFOA , LPDWORD ,BOOL ,DWORD); -INTERNETAPI HANDLE WINAPI RetrieveUrlCacheEntryStreamW(LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW , - LPDWORD ,BOOL ,DWORD); -#define RetrieveUrlCacheEntryStream WINELIB_NAME_AW(RetrieveUrlCacheEntryStream) +INTERNETAPI +HANDLE +WINAPI +RetrieveUrlCacheEntryStreamA( + _In_ LPCSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _In_ BOOL fRandomRead, + _Reserved_ DWORD dwReserved); -BOOLAPI ReadUrlCacheEntryStream( HANDLE ,DWORD ,LPVOID ,LPDWORD ,DWORD ); -BOOLAPI UnlockUrlCacheEntryStream( HANDLE ,DWORD ); -BOOLAPI GetUrlCacheEntryInfoA(LPCSTR ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD); -BOOLAPI GetUrlCacheEntryInfoW(LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD); -#define GetUrlCacheEntryInfo WINELIB_NAME_AW(GetUrlCacheEntryInfo) +INTERNETAPI +HANDLE +WINAPI +RetrieveUrlCacheEntryStreamW( + _In_ LPCWSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _In_ BOOL fRandomRead, + _Reserved_ DWORD dwReserved); -BOOLAPI GetUrlCacheEntryInfoExA( - LPCSTR ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD ,LPSTR ,LPDWORD ,LPVOID ,DWORD); -BOOLAPI GetUrlCacheEntryInfoExW( - LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD ,LPWSTR ,LPDWORD ,LPVOID ,DWORD); -#define GetUrlCacheEntryInfoEx WINELIB_NAME_AW(GetUrlCacheEntryInfoEx) +#define RetrieveUrlCacheEntryStream WINELIB_NAME_AW(RetrieveUrlCacheEntryStream) + +BOOLAPI +ReadUrlCacheEntryStream( + _In_ HANDLE hUrlCacheStream, + _In_ DWORD dwLocation, + _Out_writes_bytes_(*lpdwLen) __out_data_source(NETWORK) LPVOID lpBuffer, + _Inout_ LPDWORD lpdwLen, + _Reserved_ DWORD Reserved); + +BOOLAPI UnlockUrlCacheEntryStream(_In_ HANDLE, _Reserved_ DWORD); + +BOOLAPI +GetUrlCacheEntryInfoA( + _In_ LPCSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + _Inout_opt_ LPDWORD lpcbCacheEntryInfo); + +BOOLAPI +GetUrlCacheEntryInfoW( + _In_ LPCWSTR lpszUrlName, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, + _Inout_opt_ LPDWORD lpcbCacheEntryInfo); + +#define GetUrlCacheEntryInfo WINELIB_NAME_AW(GetUrlCacheEntryInfo) + +BOOLAPI +GetUrlCacheEntryInfoExA( + _In_ LPCSTR lpszUrl, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + _Inout_opt_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPSTR lpszRedirectUrl, + _Reserved_ LPDWORD lpcbRedirectUrl, + _Reserved_ LPVOID lpReserved, + _In_ DWORD dwFlags); + +BOOLAPI +GetUrlCacheEntryInfoExW( + _In_ LPCWSTR lpszUrl, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, + _Inout_opt_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPWSTR lpszRedirectUrl, + _Reserved_ LPDWORD lpcbRedirectUrl, + _Reserved_ LPVOID lpReserved, + _In_ DWORD dwFlags); + +#define GetUrlCacheEntryInfoEx WINELIB_NAME_AW(GetUrlCacheEntryInfoEx) #define CACHE_ENTRY_ATTRIBUTE_FC 0x00000004 #define CACHE_ENTRY_HITRATE_FC 0x00000010 @@ -1610,55 +2287,185 @@ BOOLAPI GetUrlCacheEntryInfoExW( #define CACHE_ENTRY_EXEMPT_DELTA_FC 0x00000800 -BOOLAPI SetUrlCacheEntryInfoA(LPCSTR ,LPINTERNET_CACHE_ENTRY_INFOA ,DWORD); -BOOLAPI SetUrlCacheEntryInfoW(LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW ,DWORD); -#define SetUrlCacheEntryInfo WINELIB_NAME_AW(SetUrlCacheEntryInfo) +BOOLAPI +SetUrlCacheEntryInfoA( + _In_ LPCSTR, + _In_ LPINTERNET_CACHE_ENTRY_INFOA, + _In_ DWORD); + +BOOLAPI +SetUrlCacheEntryInfoW( + _In_ LPCWSTR, + _In_ LPINTERNET_CACHE_ENTRY_INFOW, + _In_ DWORD); + +#define SetUrlCacheEntryInfo WINELIB_NAME_AW(SetUrlCacheEntryInfo) typedef LONGLONG GROUPID; -INTERNETAPI GROUPID WINAPI CreateUrlCacheGroup(DWORD,LPVOID); -BOOLAPI DeleteUrlCacheGroup(GROUPID ,DWORD ,LPVOID); +INTERNETAPI GROUPID WINAPI CreateUrlCacheGroup(_In_ DWORD, _Reserved_ LPVOID); +BOOLAPI DeleteUrlCacheGroup(_In_ GROUPID, _In_ DWORD, _Reserved_ LPVOID); -INTERNETAPI HANDLE WINAPI FindFirstUrlCacheGroup(DWORD,DWORD,LPVOID,DWORD,GROUPID*,LPVOID); -BOOLAPI FindNextUrlCacheGroup(HANDLE,GROUPID*,LPVOID); +INTERNETAPI +HANDLE +WINAPI +FindFirstUrlCacheGroup( + _In_ DWORD, + _In_ DWORD, + _Reserved_ LPVOID, + _Reserved_ DWORD, + _Out_ GROUPID*, + _Reserved_ LPVOID); -BOOLAPI GetUrlCacheGroupAttributeA(GROUPID,DWORD,DWORD,LPINTERNET_CACHE_GROUP_INFOA,LPDWORD,LPVOID); -BOOLAPI GetUrlCacheGroupAttributeW(GROUPID,DWORD,DWORD,LPINTERNET_CACHE_GROUP_INFOW,LPDWORD,LPVOID); -#define GetUrlCacheGroupAttribute WINELIB_NAME_AW(GetUrlCacheGroupAttribute) +BOOLAPI FindNextUrlCacheGroup(_In_ HANDLE, _Out_ GROUPID*, _Reserved_ LPVOID); + +BOOLAPI +GetUrlCacheGroupAttributeA( + _In_ GROUPID gid, + _Reserved_ DWORD dwFlags, + _In_ DWORD dwAttributes, + _Out_writes_bytes_(*lpcbGroupInfo) LPINTERNET_CACHE_GROUP_INFOA lpGroupInfo, + _Inout_ LPDWORD lpcbGroupInfo, + _Reserved_ LPVOID lpReserved); + +BOOLAPI +GetUrlCacheGroupAttributeW( + _In_ GROUPID gid, + _Reserved_ DWORD dwFlags, + _In_ DWORD dwAttributes, + _Out_writes_bytes_(*lpcbGroupInfo) LPINTERNET_CACHE_GROUP_INFOW lpGroupInfo, + _Inout_ LPDWORD lpcbGroupInfo, + _Reserved_ LPVOID lpReserved); + +#define GetUrlCacheGroupAttribute WINELIB_NAME_AW(GetUrlCacheGroupAttribute) #define INTERNET_CACHE_GROUP_ADD 0 #define INTERNET_CACHE_GROUP_REMOVE 1 -BOOLAPI SetUrlCacheEntryGroupA(LPCSTR,DWORD,GROUPID,LPBYTE,DWORD,LPVOID); -BOOLAPI SetUrlCacheEntryGroupW(LPCWSTR,DWORD,GROUPID,LPBYTE,DWORD,LPVOID); -#define SetUrlCacheEntryGroup WINELIB_NAME_AW(SetUrlCacheEntryGroup) +BOOLAPI +SetUrlCacheEntryGroupA( + _In_ LPCSTR, + _In_ DWORD, + _In_ GROUPID, + _Reserved_ LPBYTE, + _Reserved_ DWORD, + _Reserved_ LPVOID); -BOOLAPI SetUrlCacheGroupAttributeA(GROUPID,DWORD,DWORD,LPINTERNET_CACHE_GROUP_INFOA,LPVOID); -BOOLAPI SetUrlCacheGroupAttributeW(GROUPID,DWORD,DWORD,LPINTERNET_CACHE_GROUP_INFOW,LPVOID); -#define SetUrlCacheGroupAttribute WINELIB_NAME_AW(SetUrlCacheGroupAttribute) +BOOLAPI +SetUrlCacheEntryGroupW( + _In_ LPCWSTR, + _In_ DWORD, + _In_ GROUPID, + _Reserved_ LPBYTE, + _Reserved_ DWORD, + _Reserved_ LPVOID); -INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryExA( - LPCSTR ,DWORD ,DWORD ,GROUPID ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD ,LPVOID ,LPDWORD ,LPVOID ); -INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryExW( - LPCWSTR ,DWORD ,DWORD ,GROUPID ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD ,LPVOID ,LPDWORD ,LPVOID ); -#define FindFirstUrlCacheEntryEx WINELIB_NAME_AW(FindFirstUrlCacheEntryEx) +#define SetUrlCacheEntryGroup WINELIB_NAME_AW(SetUrlCacheEntryGroup) -BOOLAPI FindNextUrlCacheEntryExA(HANDLE ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD ,LPVOID ,LPDWORD ,LPVOID); -BOOLAPI FindNextUrlCacheEntryExW(HANDLE ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD ,LPVOID ,LPDWORD ,LPVOID); -#define FindNextUrlCacheEntryEx WINELIB_NAME_AW(FindNextUrlCacheEntryEx) +BOOLAPI +SetUrlCacheGroupAttributeA( + _In_ GROUPID, + _Reserved_ DWORD, + _In_ DWORD, + _In_ LPINTERNET_CACHE_GROUP_INFOA, + _Reserved_ LPVOID); -INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryA(LPCSTR ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD); -INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryW(LPCWSTR ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD); -#define FindFirstUrlCacheEntry WINELIB_NAME_AW(FindFirstUrlCacheEntry) +BOOLAPI +SetUrlCacheGroupAttributeW( + _In_ GROUPID, + _Reserved_ DWORD, + _In_ DWORD, + _In_ LPINTERNET_CACHE_GROUP_INFOW, + _Reserved_ LPVOID); -BOOLAPI FindNextUrlCacheEntryA(HANDLE ,LPINTERNET_CACHE_ENTRY_INFOA ,LPDWORD); -BOOLAPI FindNextUrlCacheEntryW(HANDLE ,LPINTERNET_CACHE_ENTRY_INFOW ,LPDWORD); -#define FindNextUrlCacheEntry WINELIB_NAME_AW(FindNextUrlCacheEntry) +#define SetUrlCacheGroupAttribute WINELIB_NAME_AW(SetUrlCacheGroupAttribute) -BOOLAPI FindCloseUrlCache(HANDLE); +INTERNETAPI +HANDLE +WINAPI +FindFirstUrlCacheEntryExA( + _In_opt_ LPCSTR lpszUrlSearchPattern, + _In_ DWORD dwFlags, + _In_ DWORD dwFilter, + _In_ GROUPID GroupId, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPVOID lpGroupAttributes, + _Reserved_ LPDWORD lpcbGroupAttributes, + _Reserved_ LPVOID lpReserved); -BOOLAPI DeleteUrlCacheEntryA(LPCSTR); -BOOLAPI DeleteUrlCacheEntryW(LPCWSTR); +INTERNETAPI +HANDLE +WINAPI +FindFirstUrlCacheEntryExW( + _In_opt_ LPCWSTR lpszUrlSearchPattern, + _In_ DWORD dwFlags, + _In_ DWORD dwFilter, + _In_ GROUPID GroupId, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPVOID lpGroupAttributes, + _Reserved_ LPDWORD lpcbGroupAttributes, + _Reserved_ LPVOID lpReserved); + +#define FindFirstUrlCacheEntryEx WINELIB_NAME_AW(FindFirstUrlCacheEntryEx) + +BOOLAPI +FindNextUrlCacheEntryExA( + _In_ HANDLE hEnumHandle, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpNextCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPVOID lpGroupAttributes, + _Reserved_ LPDWORD lpcbGroupAttributes, + _Reserved_ LPVOID lpReserved); + +BOOLAPI +FindNextUrlCacheEntryExW( + _In_ HANDLE hEnumHandle, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpNextCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo, + _Reserved_ LPVOID lpGroupAttributes, + _Reserved_ LPDWORD lpcbGroupAttributes, + _Reserved_ LPVOID lpReserved); + +#define FindNextUrlCacheEntryEx WINELIB_NAME_AW(FindNextUrlCacheEntryEx) + +INTERNETAPI +HANDLE +WINAPI +FindFirstUrlCacheEntryA( + _In_opt_ LPCSTR lpszUrlSearchPattern, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo); + +INTERNETAPI +HANDLE +WINAPI +FindFirstUrlCacheEntryW( + _In_opt_ LPCWSTR lpszUrlSearchPattern, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo); + +#define FindFirstUrlCacheEntry WINELIB_NAME_AW(FindFirstUrlCacheEntry) + +BOOLAPI +FindNextUrlCacheEntryA( + _In_ HANDLE hEnumHandle, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOA lpNextCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo); + +BOOLAPI +FindNextUrlCacheEntryW( + _In_ HANDLE hEnumHandle, + _Inout_updates_bytes_opt_(*lpcbCacheEntryInfo) LPINTERNET_CACHE_ENTRY_INFOW lpNextCacheEntryInfo, + _Inout_ LPDWORD lpcbCacheEntryInfo); + +#define FindNextUrlCacheEntry WINELIB_NAME_AW(FindNextUrlCacheEntry) + +BOOLAPI FindCloseUrlCache(_In_ HANDLE); + +BOOLAPI DeleteUrlCacheEntryA(_In_ LPCSTR); +BOOLAPI DeleteUrlCacheEntryW(_In_ LPCWSTR); #define DeleteUrlCacheEntry WINELIB_NAME_AW(DeleteUrlCacheEntry) /* FCS_ flags and FreeUrlCacheSpace are no longer documented */ @@ -1670,31 +2477,50 @@ BOOLAPI FreeUrlCacheSpaceA(LPCSTR ,DWORD ,DWORD); BOOLAPI FreeUrlCacheSpaceW(LPCWSTR ,DWORD ,DWORD); #define FreeUrlCacheSpace WINELIB_NAME_AW(FreeUrlCacheSpace) +INTERNETAPI +DWORD +WINAPI +InternetDialA( + _In_ HWND, + _In_opt_ LPSTR, + _In_ DWORD, + _Out_ DWORD_PTR*, + _Reserved_ DWORD); + +INTERNETAPI +DWORD +WINAPI +InternetDialW( + _In_ HWND, + _In_opt_ LPWSTR, + _In_ DWORD, + _Out_ DWORD_PTR*, + _Reserved_ DWORD); -INTERNETAPI DWORD WINAPI InternetDialA(HWND ,LPSTR ,DWORD ,DWORD_PTR* ,DWORD); -INTERNETAPI DWORD WINAPI InternetDialW(HWND ,LPWSTR ,DWORD ,DWORD_PTR* ,DWORD); #define InternetDial WINELIB_NAME_AW(InternetDial) - #define INTERNET_DIAL_UNATTENDED 0x8000 -INTERNETAPI DWORD WINAPI InternetHangUp(DWORD_PTR ,DWORD); -BOOLAPI CreateMD5SSOHash(PWSTR,PWSTR,PWSTR,PBYTE); +INTERNETAPI DWORD WINAPI InternetHangUp(_In_ DWORD_PTR, _Reserved_ DWORD); +BOOLAPI CreateMD5SSOHash(_In_ PWSTR, _In_ PWSTR, _In_ PWSTR, _Out_ PBYTE); #define INTERENT_GOONLINE_REFRESH 0x00000001 #define INTERENT_GOONLINE_MASK 0x00000001 -INTERNETAPI BOOL WINAPI InternetGoOnlineA(LPSTR ,HWND ,DWORD); -INTERNETAPI BOOL WINAPI InternetGoOnlineW(LPWSTR ,HWND ,DWORD); + +BOOLAPI InternetGoOnlineA(_In_opt_ LPSTR, _In_ HWND, _In_ DWORD); +BOOLAPI InternetGoOnlineW(_In_opt_ LPWSTR, _In_ HWND, _In_ DWORD); #define InternetGoOnline WINELIB_NAME_AW(InternetGoOnline) -INTERNETAPI BOOL WINAPI InternetAutodial(DWORD,HWND); + +BOOLAPI InternetAutodial(_In_ DWORD, _In_opt_ HWND); #define INTERNET_AUTODIAL_FORCE_ONLINE 1 #define INTERNET_AUTODIAL_FORCE_UNATTENDED 2 #define INTERNET_AUTODIAL_FAILIFSECURITYCHECK 4 #define INTERNET_AUTODIAL_FLAGS_MASK (INTERNET_AUTODIAL_FORCE_ONLINE | INTERNET_AUTODIAL_FORCE_UNATTENDED | INTERNET_AUTODIAL_FAILIFSECURITYCHECK) -INTERNETAPI BOOL WINAPI InternetAutodialHangup(DWORD); -INTERNETAPI BOOL WINAPI InternetGetConnectedState(LPDWORD ,DWORD); + +BOOLAPI InternetAutodialHangup(_Reserved_ DWORD); +BOOLAPI InternetGetConnectedState(_Out_ LPDWORD, _Reserved_ DWORD); #define INTERNET_CONNECTION_MODEM 1 #define INTERNET_CONNECTION_LAN 2 @@ -1711,20 +2537,38 @@ typedef DWORD (CALLBACK *PFN_DIAL_HANDLER) (HWND,LPCSTR,DWORD,LPDWORD); #define INTERNET_CUSTOMDIAL_WILL_SUPPLY_STATE 2 #define INTERNET_CUSTOMDIAL_CAN_HANGUP 4 -INTERNETAPI BOOL WINAPI InternetSetDialStateA(LPCSTR ,DWORD ,DWORD); -INTERNETAPI BOOL WINAPI InternetSetDialStateW(LPCWSTR ,DWORD ,DWORD); +BOOLAPI InternetSetDialStateA(_In_opt_ LPCSTR, _In_ DWORD, _Reserved_ DWORD); +BOOLAPI InternetSetDialStateW(_In_opt_ LPCWSTR, _In_ DWORD, _Reserved_ DWORD); #define InternetSetDialState WINELIB_NAME_AW(InternetSetDialState) + #define INTERNET_DIALSTATE_DISCONNECTED 1 -BOOL WINAPI InternetGetConnectedStateExA(LPDWORD, LPSTR, DWORD, DWORD); -BOOL WINAPI InternetGetConnectedStateExW(LPDWORD, LPWSTR, DWORD, DWORD); +BOOLAPI +InternetGetConnectedStateExA( + _Out_opt_ LPDWORD lpdwFlags, + _Out_writes_opt_(cchNameLen) LPSTR lpszConnectionName, + _In_ DWORD cchNameLen, + _Reserved_ DWORD dwReserved); + +BOOLAPI +InternetGetConnectedStateExW( + _Out_opt_ LPDWORD lpdwFlags, + _Out_writes_opt_(cchNameLen) LPWSTR lpszConnectionName, + _In_ DWORD cchNameLen, + _Reserved_ DWORD dwReserved); + #define InternetGetConnectedStateEx WINELIB_NAME_AW(InternetGetConnectedStateEx) -BOOL WINAPI InternetInitializeAutoProxyDll(DWORD); -BOOL WINAPI DetectAutoProxyUrl(LPSTR, DWORD, DWORD); +BOOLAPI InternetInitializeAutoProxyDll(_In_ DWORD); + +BOOLAPI +DetectAutoProxyUrl( + _Out_writes_(cchAutoProxyUrl) PSTR pszAutoProxyUrl, + _In_ DWORD cchAutoProxyUrl, + _In_ DWORD dwDetectFlags); #ifdef __cplusplus } #endif -#endif +#endif /* _WINE_WININET_H_ */ diff --git a/include/reactos/mc/CMakeLists.txt b/include/reactos/mc/CMakeLists.txt index 1e62d5fe576..8037a7c2575 100644 --- a/include/reactos/mc/CMakeLists.txt +++ b/include/reactos/mc/CMakeLists.txt @@ -7,7 +7,8 @@ list(APPEND UNICODE_SOURCE neteventmsg.mc ntiologc.mc ntstatus.mc - pciclass.mc) + pciclass.mc + sacmsg.mc) add_message_headers(ANSI ${ANSI_SOURCE}) # FIXME: this needs testing before switching to unicode diff --git a/include/reactos/mc/sacmsg.mc b/include/reactos/mc/sacmsg.mc index dce4a07f41f..4d3052c3d42 100644 --- a/include/reactos/mc/sacmsg.mc +++ b/include/reactos/mc/sacmsg.mc @@ -1,17 +1,17 @@ MessageId=1 -SymbolicName=SACDRV_1 +SymbolicName=SAC_INIT_STATUS Language=English Computer is booting, SAC started and initialized.\n\nUse the \"ch -?\" command for information about using channels.\nUse the \"?\" command for general help. . MessageId=2 -SymbolicName=SACDRV_2 +SymbolicName=SAC_NEWLINE Language=English . MessageId=3 -SymbolicName=SACDRV_3 +SymbolicName=SAC_PROMPT Language=English SAC>%0 . @@ -59,9 +59,9 @@ Paging is now OFF. . MessageId=11 -SymbolicName=SACDRV_11 +SymbolicName=SAC_OUT_OF_MEMORY_PROMPT Language=English -Paging is now OFF. +THIS LOOKS LIKE A BUG??? . MessageId=12 @@ -173,7 +173,7 @@ lock Lock access to Command Prompt channels. . MessageId=48 -SymbolicName=SACDRV_48 +SymbolicName=SAC_FAIL_PROMPT Language=English Failed with status 0x%%X. . @@ -269,13 +269,13 @@ SAC cannot raise the process priority any higher. . MessageId=65 -SymbolicName=SACDRV_65 +SymbolicName=SAC_SHUTDOWN_FAIL_PROMPT Language=English SAC failed to shutdown the system. . MessageId=66 -SymbolicName=SACDRV_66 +SymbolicName=SAC_RESTART_FAIL_PROMPT Language=English SAC failed to restart the system. . @@ -551,19 +551,19 @@ ch Channel management commands. Use ch -? for more help. . MessageId=113 -SymbolicName=SACDRV_113 +SymbolicName=SAC_RESTART_TIME_PROMPT Language=English Time since last reboot: %%d:%%02d:%%02d . MessageId=114 -SymbolicName=SACDRV_114 +SymbolicName=SAC_RESTART_PROMPT Language=English SAC preparing to restart the system. . MessageId=115 -SymbolicName=SACDRV_115 +SymbolicName=SAC_SHUTDOWN_PROMPT Language=English SAC preparing to shutdown the system. . @@ -641,13 +641,13 @@ Error: There is no channel present at the specified index. . MessageId=144 -SymbolicName=SACDRV_144 +SymbolicName=SAC_CHANNEL_NAME Language=English SAC%0 . MessageId=145 -SymbolicName=SACDRV_145 +SymbolicName=SAC_CHANNEL_DESCRIPTION Language=English Special Administration Console%0 . diff --git a/ntoskrnl/io/iomgr/iorsrce.c b/ntoskrnl/io/iomgr/iorsrce.c index febd24b5b3d..a498d6d40fb 100644 --- a/ntoskrnl/io/iomgr/iorsrce.c +++ b/ntoskrnl/io/iomgr/iorsrce.c @@ -908,37 +908,86 @@ IoReportResourceUsage(PUNICODE_STRING DriverClassName, return STATUS_SUCCESS; } -/* - * @halfplemented - */ -NTSTATUS NTAPI -IoAssignResources(PUNICODE_STRING RegistryPath, - PUNICODE_STRING DriverClassName, - PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT DeviceObject, - PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources, - PCM_RESOURCE_LIST* AllocatedResources) +NTSTATUS +NTAPI +IopLegacyResourceAllocation(IN ARBITER_REQUEST_SOURCE AllocationType, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject OPTIONAL, + IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements, + IN OUT PCM_RESOURCE_LIST *AllocatedResources) { NTSTATUS Status; - - DPRINT1("IoAssignResources is halfplemented!\n"); - *AllocatedResources = NULL; - Status = IopFixupResourceListWithRequirements(RequestedResources, + DPRINT1("IopLegacyResourceAllocation is halfplemented!\n"); + + Status = IopFixupResourceListWithRequirements(ResourceRequirements, AllocatedResources); if (!NT_SUCCESS(Status)) { if (Status == STATUS_CONFLICTING_ADDRESSES) + { DPRINT1("Denying an attempt to claim resources currently in use by another device!\n"); - + } + return Status; } - + /* TODO: Claim resources in registry */ - return STATUS_SUCCESS; } +/* + * @implemented + */ +NTSTATUS +NTAPI +IoAssignResources(IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources, + IN OUT PCM_RESOURCE_LIST* AllocatedResources) +{ + PDEVICE_NODE DeviceNode; + + /* Do we have a DO? */ + if (DeviceObject) + { + /* Get its device node */ + DeviceNode = IopGetDeviceNode(DeviceObject); + if ((DeviceNode) && !(DeviceNode->Flags & DNF_LEGACY_RESOURCE_DEVICENODE)) + { + /* New drivers should not call this API */ + KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, + 0, + 0, + (ULONG_PTR)DeviceObject, + (ULONG_PTR)DriverObject); + } + } + + /* Did the driver supply resources? */ + if (RequestedResources) + { + /* Make sure there's actually something useful in them */ + if (!(RequestedResources->AlternativeLists) || !(RequestedResources->List[0].Count)) + { + /* Empty resources are no resources */ + RequestedResources = NULL; + } + } + + /* Initialize output if given */ + if (AllocatedResources) *AllocatedResources = NULL; + + /* Call internal helper function */ + return IopLegacyResourceAllocation(ArbiterRequestLegacyAssigned, + DriverObject, + DeviceObject, + RequestedResources, + AllocatedResources); +} + /* * FUNCTION: * Reads and returns Hardware information from the appropriate hardware registry key. diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index 3aca4ce583b..44fa2ea0973 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -2268,8 +2268,6 @@ IopEnumerateDevice( &DeviceNode->InstancePath); } - DeviceNode->Flags &= ~DNF_NEED_TO_ENUM; - DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n"); Stack.Parameters.QueryDeviceRelations.Type = BusRelations; diff --git a/ntoskrnl/ps/process.c b/ntoskrnl/ps/process.c index 2a00366c896..1f881e65826 100644 --- a/ntoskrnl/ps/process.c +++ b/ntoskrnl/ps/process.c @@ -369,7 +369,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, "ProcessHandle: %p Parent: %p\n", ProcessHandle, ParentProcess); /* Validate flags */ - if (Flags & ~PS_ALL_FLAGS) return STATUS_INVALID_PARAMETER; + if (Flags & ~PROCESS_CREATE_FLAGS_LEGAL_MASK) return STATUS_INVALID_PARAMETER; /* Check for parent */ if (ParentProcess) @@ -508,7 +508,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, Process->DebugPort = DebugObject; /* Check if the caller doesn't want the debug stuff inherited */ - if (Flags & PS_NO_DEBUG_INHERIT) + if (Flags & PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT) { /* Set the process flag */ InterlockedOr((PLONG)&Process->Flags, PSF_NO_DEBUG_INHERIT_BIT); @@ -595,7 +595,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, } /* Initialize object manager for the process */ - Status = ObInitProcess(Flags & PS_INHERIT_HANDLES ? Parent : NULL, + Status = ObInitProcess(Flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES ? + Parent : NULL, Process); if (!NT_SUCCESS(Status)) goto CleanupWithRef; } @@ -643,7 +644,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, else { /* This is the initial system process */ - Flags &= ~PS_LARGE_PAGES; + Flags &= ~PROCESS_CREATE_FLAGS_LARGE_PAGES; Status = MmInitializeProcessAddressSpace(Process, NULL, NULL, @@ -1347,9 +1348,9 @@ NtCreateProcess(OUT PHANDLE ProcessHandle, "Parent: %p Attributes: %p\n", ParentProcess, ObjectAttributes); /* Set new-style flags */ - if ((ULONG)SectionHandle & 1) Flags = PS_REQUEST_BREAKAWAY; - if ((ULONG)DebugPort & 1) Flags |= PS_NO_DEBUG_INHERIT; - if (InheritObjectTable) Flags |= PS_INHERIT_HANDLES; + if ((ULONG)SectionHandle & 1) Flags |= PROCESS_CREATE_FLAGS_BREAKAWAY; + if ((ULONG)DebugPort & 1) Flags |= PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT; + if (InheritObjectTable) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES; /* Call the new API */ return NtCreateProcessEx(ProcessHandle, diff --git a/win32ss/user/winsrv/consrv/condrv/console.c b/win32ss/user/winsrv/consrv/condrv/console.c index 861c4721f74..0c4cb6ac9ec 100644 --- a/win32ss/user/winsrv/consrv/condrv/console.c +++ b/win32ss/user/winsrv/consrv/condrv/console.c @@ -143,9 +143,13 @@ static NTSTATUS RemoveConsoleByHandle(IN HANDLE Handle) { NTSTATUS Status = STATUS_SUCCESS; - ULONG Index = HandleToULong(Handle) >> 2; PCONSOLE Console; + BOOLEAN ValidHandle = ((HandleToULong(Handle) & 0x3) == 0x3); + ULONG Index = HandleToULong(Handle) >> 2; + + if (!ValidHandle) return STATUS_INVALID_HANDLE; + ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) || (ConsoleList != NULL && ConsoleListSize != 0) ); @@ -339,10 +343,13 @@ ConDrvValidateConsole(OUT PCONSOLE* Console, IN BOOLEAN LockConsole) { BOOLEAN RetVal = FALSE; - - ULONG Index = HandleToULong(ConsoleHandle) >> 2; PCONSOLE ValidatedConsole; + BOOLEAN ValidHandle = ((HandleToULong(ConsoleHandle) & 0x3) == 0x3); + ULONG Index = HandleToULong(ConsoleHandle) >> 2; + + if (!ValidHandle) return FALSE; + if (!Console) return FALSE; *Console = NULL; diff --git a/win32ss/user/winsrv/consrv/console.c b/win32ss/user/winsrv/consrv/console.c index 9403daa081f..932d623ff21 100644 --- a/win32ss/user/winsrv/consrv/console.c +++ b/win32ss/user/winsrv/consrv/console.c @@ -159,7 +159,7 @@ VOID FASTCALL ConSrvReleaseConsole(PCONSOLE Console, BOOL WasConsoleLocked) { - /* Just call the driver*/ + /* Just call the driver */ ConDrvReleaseConsole(Console, WasConsoleLocked); } diff --git a/win32ss/user/winsrv/consrv/handle.c b/win32ss/user/winsrv/consrv/handle.c index f5ef3e755f3..9e6ac97ba3b 100644 --- a/win32ss/user/winsrv/consrv/handle.c +++ b/win32ss/user/winsrv/consrv/handle.c @@ -387,6 +387,8 @@ ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData, RtlEnterCriticalSection(&ProcessData->HandleTableLock); ASSERT(ProcessData->HandleTable); + // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) || + // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) ); if (Index >= ProcessData->HandleTableSize || (Object = ProcessData->HandleTable[Index].Object) == NULL) @@ -781,6 +783,9 @@ CSR_API(SrvVerifyConsoleIoHandle) RtlEnterCriticalSection(&ProcessData->HandleTableLock); + // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) || + // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) ); + if (!IsConsoleHandle(ConsoleHandle) || Index >= ProcessData->HandleTableSize || ProcessData->HandleTable[Index].Object == NULL) @@ -816,6 +821,9 @@ CSR_API(SrvDuplicateHandle) RtlEnterCriticalSection(&ProcessData->HandleTableLock); + // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) || + // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) ); + if ( /** !IsConsoleHandle(ConsoleHandle) || **/ Index >= ProcessData->HandleTableSize || (Entry = &ProcessData->HandleTable[Index])->Object == NULL)