diff --git a/.gitignore b/.gitignore index 314e6954e1e..732ceba80ea 100644 --- a/.gitignore +++ b/.gitignore @@ -59,7 +59,6 @@ artifacts/ StyleCopReport.xml # Files built by Visual Studio -*_i.c *_p.c *_i.h *.ilk diff --git a/Microsoft.Dotnet.Wpf.sln b/Microsoft.Dotnet.Wpf.sln index ce33ffb5fc1..b37679fab27 100644 --- a/Microsoft.Dotnet.Wpf.sln +++ b/Microsoft.Dotnet.Wpf.sln @@ -159,6 +159,22 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WindowsFormsIntegration-ref EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PresentationUI-ref", "src\Microsoft.DotNet.Wpf\src\PresentationUI\ref\PresentationUI-ref.csproj", "{C79A5A35-2470-46C0-A2B6-BA0633A80420}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "redist", "redist", "{DDED00A7-24FD-4AEF-B264-2150F0E59B4D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3DCompiler", "src\Microsoft.DotNet.Wpf\redist\D3DCompiler\D3DCompiler.vcxproj", "{60E8E057-79E1-4860-A015-23C9587434F7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCRuntime", "src\Microsoft.DotNet.Wpf\redist\VCRuntime\VCRuntime.vcxproj", "{B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Unmanaged", "Unmanaged", "{4557C5C6-10B1-475C-8279-5511955D1C29}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Managed", "Managed", "{2EE4A2DA-70B3-4767-9D18-618DA0FE3105}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TabLib", "src\Microsoft.DotNet.Wpf\src\PenImc\tablib\TabLib.vcxproj", "{8F91EB3A-C530-4CEA-90BF-AFC8165B6456}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PenImc", "PenImc", "{956D1AA8-9E02-49CA-A496-689D7024D444}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PenImc", "src\Microsoft.DotNet.Wpf\src\PenImc\dll\PenImc.vcxproj", "{8383C663-E8D0-4D2D-B65A-FE4A253E3319}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -925,24 +941,97 @@ Global {C79A5A35-2470-46C0-A2B6-BA0633A80420}.Release|x64.Build.0 = Release|x64 {C79A5A35-2470-46C0-A2B6-BA0633A80420}.Release|x86.ActiveCfg = Release|Any CPU {C79A5A35-2470-46C0-A2B6-BA0633A80420}.Release|x86.Build.0 = Release|Any CPU + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|Any CPU.Build.0 = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|Any CPU.Deploy.0 = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|x64.ActiveCfg = Debug|x64 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|x64.Build.0 = Debug|x64 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|x86.ActiveCfg = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|x86.Build.0 = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|x86.Deploy.0 = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|Any CPU.ActiveCfg = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|Any CPU.Build.0 = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|Any CPU.Deploy.0 = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|x64.ActiveCfg = Release|x64 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|x64.Build.0 = Release|x64 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|x86.ActiveCfg = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|x86.Build.0 = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|x86.Deploy.0 = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|Any CPU.Build.0 = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|Any CPU.Deploy.0 = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|x64.ActiveCfg = Debug|x64 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|x64.Build.0 = Debug|x64 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|x86.ActiveCfg = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|x86.Build.0 = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|x86.Deploy.0 = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|Any CPU.ActiveCfg = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|Any CPU.Build.0 = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|Any CPU.Deploy.0 = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|x64.ActiveCfg = Release|x64 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|x64.Build.0 = Release|x64 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|x86.ActiveCfg = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|x86.Build.0 = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|x86.Deploy.0 = Release|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|Any CPU.Build.0 = Debug|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|Any CPU.Deploy.0 = Debug|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|x64.ActiveCfg = Debug|x64 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|x64.Build.0 = Debug|x64 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|x86.ActiveCfg = Debug|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|x86.Build.0 = Debug|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|x86.Deploy.0 = Debug|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|Any CPU.ActiveCfg = Release|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|Any CPU.Build.0 = Release|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|Any CPU.Deploy.0 = Release|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|x64.ActiveCfg = Release|x64 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|x64.Build.0 = Release|x64 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|x86.ActiveCfg = Release|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|x86.Build.0 = Release|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|x86.Deploy.0 = Release|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|Any CPU.Build.0 = Debug|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|Any CPU.Deploy.0 = Debug|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|x64.ActiveCfg = Debug|x64 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|x64.Build.0 = Debug|x64 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|x86.ActiveCfg = Debug|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|x86.Build.0 = Debug|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|x86.Deploy.0 = Debug|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|Any CPU.ActiveCfg = Release|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|Any CPU.Build.0 = Release|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|Any CPU.Deploy.0 = Release|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|x64.ActiveCfg = Release|x64 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|x64.Build.0 = Release|x64 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|x86.ActiveCfg = Release|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|x86.Build.0 = Release|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|x86.Deploy.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {9AC36357-34B7-40A1-95CA-FE9F46D089A7} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} {BF20132A-191F-4D34-9A1B-831772A6DFCF} = {0159B0F1-0626-4BED-8D1B-CBFF4F12C369} {C847934A-828C-4EBB-A004-B0E97C8313F4} = {BF20132A-191F-4D34-9A1B-831772A6DFCF} {9A7E395B-E859-40E2-809D-EFB72CF3A2EE} = {BF20132A-191F-4D34-9A1B-831772A6DFCF} {8A2ABE39-2D50-48CA-AC32-078BBA32757A} = {0159B0F1-0626-4BED-8D1B-CBFF4F12C369} {B73BB4AB-68DE-4B91-BBB0-AB4F2D504AC3} = {8A2ABE39-2D50-48CA-AC32-078BBA32757A} {BFF6C118-3369-43B5-ACA6-D65ED00EEBE0} = {22D643D8-87D6-4FE8-9632-58A3CD3DC7CB} + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} {1D4C8AD7-12E7-4987-98AF-AEE79F53E494} = {0159B0F1-0626-4BED-8D1B-CBFF4F12C369} {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1} = {1D4C8AD7-12E7-4987-98AF-AEE79F53E494} {22D643D8-87D6-4FE8-9632-58A3CD3DC7CB} = {0159B0F1-0626-4BED-8D1B-CBFF4F12C369} + {FA69991B-9696-42D0-A5C7-F5E73F0DEE9E} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} + {50A5318F-3B9A-48B9-9615-D5FA9D6D9C3E} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} + {74C63A45-EAE5-407A-9F89-E0C6BC604841} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} + {B0C1157E-8664-44C4-AD8E-35CD6A78C769} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} + {4572CF94-B209-4479-85AB-59CA87BF5AFA} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} {2DD6F2F8-DFF4-4EE1-9D48-0FD692DB084D} = {4572CF94-B209-4479-85AB-59CA87BF5AFA} {D242FDF9-F132-4154-BB9F-3F85C39F6F4C} = {4572CF94-B209-4479-85AB-59CA87BF5AFA} {4C99DEEE-ED7A-4225-8127-3B1E6EDB39D0} = {4572CF94-B209-4479-85AB-59CA87BF5AFA} {152C4B33-3B53-4180-B8BC-7BB0BC91A2ED} = {4572CF94-B209-4479-85AB-59CA87BF5AFA} + {B6F41F07-2117-49E0-A2B7-4BC6F586057B} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} + {17AA6CC2-CAE3-429C-B065-B76B8E14C632} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} {47BC9F30-4DFF-4DEB-BFFE-1EC9735E6965} = {271ED3B3-976D-4253-85F5-E98CC86993D6} {FC06FD19-DE12-42BF-908E-8391AF63DB7E} = {271ED3B3-976D-4253-85F5-E98CC86993D6} {3F4CA1F0-0FA6-4191-B29D-1A283D13C55B} = {271ED3B3-976D-4253-85F5-E98CC86993D6} @@ -971,6 +1060,8 @@ Global {2B18C965-BE75-4814-876D-8659D4A8A943} = {88264221-65BC-4E7E-8891-D26467BC250C} {25EDAA5F-CA1E-4792-9CC3-0B4373E9C77F} = {88264221-65BC-4E7E-8891-D26467BC250C} {A78C427C-F7FE-486A-8777-1701E6E81BE0} = {88264221-65BC-4E7E-8891-D26467BC250C} + {88264221-65BC-4E7E-8891-D26467BC250C} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} + {5ACFB055-649D-4A01-98C2-B0BFE7E543D6} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} {17C69C55-A365-4040-974D-06BB8BB5AF1F} = {5ACFB055-649D-4A01-98C2-B0BFE7E543D6} {0D089FF4-33B1-4009-B367-A9E5F558A6BE} = {5ACFB055-649D-4A01-98C2-B0BFE7E543D6} {C966E164-061D-411F-B358-764A80B2F39C} = {5ACFB055-649D-4A01-98C2-B0BFE7E543D6} @@ -981,13 +1072,23 @@ Global {419232AF-647C-4B99-A9E6-5F24AA65295A} = {60F4058B-D35B-42D2-B276-D44B3AC579BD} {97CFC19A-54E3-4F09-AAFD-487ED55359F6} = {60F4058B-D35B-42D2-B276-D44B3AC579BD} {CD1664AE-A70E-4DE6-A523-FFD6916E337D} = {60F4058B-D35B-42D2-B276-D44B3AC579BD} + {3B0404D6-0317-4DF3-95A4-A45B0C421910} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} + {A65AB368-1C20-4D4B-9A5B-CB3656CA05BC} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} {E0043FA2-FB86-4EFB-87DF-70B4FE10A895} = {D0AED517-9972-41CB-8751-983E4EB8F511} {DC69B536-1F6E-4A7C-B126-2057E7B03591} = {D0AED517-9972-41CB-8751-983E4EB8F511} {D224BACC-340B-4986-81D6-C695EB2B5A62} = {60F4058B-D35B-42D2-B276-D44B3AC579BD} {EA7825C4-0E99-477A-985D-0B5F0421A30A} = {60F4058B-D35B-42D2-B276-D44B3AC579BD} {598B6188-937C-448B-8E6B-925F000BC076} = {60F4058B-D35B-42D2-B276-D44B3AC579BD} + {765E6BBC-772B-4808-BB72-E85615E8F237} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} + {B8E5B99C-D162-4DCA-9C4F-90CF2CDE942E} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} + {9F3166CE-7406-4A8F-8B00-705AE57E6D35} = {2EE4A2DA-70B3-4767-9D18-618DA0FE3105} {61334087-4A73-4F17-984B-56B84D2148DA} = {D0AED517-9972-41CB-8751-983E4EB8F511} {C79A5A35-2470-46C0-A2B6-BA0633A80420} = {D0AED517-9972-41CB-8751-983E4EB8F511} + {60E8E057-79E1-4860-A015-23C9587434F7} = {DDED00A7-24FD-4AEF-B264-2150F0E59B4D} + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA} = {DDED00A7-24FD-4AEF-B264-2150F0E59B4D} + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456} = {956D1AA8-9E02-49CA-A496-689D7024D444} + {956D1AA8-9E02-49CA-A496-689D7024D444} = {4557C5C6-10B1-475C-8279-5511955D1C29} + {8383C663-E8D0-4D2D-B65A-FE4A253E3319} = {956D1AA8-9E02-49CA-A496-689D7024D444} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B4340004-DAC0-497D-B69D-CFA7CD93F567} diff --git a/src/Microsoft.DotNet.Wpf/redist/D3DCompiler/D3DCompiler.vcxproj b/src/Microsoft.DotNet.Wpf/redist/D3DCompiler/D3DCompiler.vcxproj new file mode 100644 index 00000000000..ac5e5d2caa6 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/redist/D3DCompiler/D3DCompiler.vcxproj @@ -0,0 +1,44 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + DynamicLibrary + false + + + + + + $(D3DCompilerDllBaseName)$(D3DCompilerVersion)$(WpfVersionSuffix) + + + + $(Windows10SdkPath)Redist\D3D\$(Architecture)\$(D3DCompilerDllBaseName)$(D3DCompilerVersion).dll + + + 16.0 + {60E8E057-79E1-4860-A015-23C9587434F7} + Win32Proj + + + \ No newline at end of file diff --git a/src/Microsoft.DotNet.Wpf/redist/Directory.Build.Props b/src/Microsoft.DotNet.Wpf/redist/Directory.Build.Props new file mode 100644 index 00000000000..1122b2e3100 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/redist/Directory.Build.Props @@ -0,0 +1,10 @@ + + + + true + + + + diff --git a/src/Microsoft.DotNet.Wpf/redist/Redist.sln b/src/Microsoft.DotNet.Wpf/redist/Redist.sln new file mode 100644 index 00000000000..89a601a9210 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/redist/Redist.sln @@ -0,0 +1,59 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28606.126 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCRuntime", "VCRuntime\VCRuntime.vcxproj", "{B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3DCompiler", "D3DCompiler\D3DCompiler.vcxproj", "{60E8E057-79E1-4860-A015-23C9587434F7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|AnyCPU = Debug|AnyCPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|AnyCPU = Release|AnyCPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|AnyCPU.ActiveCfg = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|AnyCPU.Build.0 = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|AnyCPU.Deploy.0 = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|x64.ActiveCfg = Debug|x64 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|x64.Build.0 = Debug|x64 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|x86.ActiveCfg = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|x86.Build.0 = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Debug|x86.Deploy.0 = Debug|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|AnyCPU.ActiveCfg = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|AnyCPU.Build.0 = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|AnyCPU.Deploy.0 = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|x64.ActiveCfg = Release|x64 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|x64.Build.0 = Release|x64 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|x86.ActiveCfg = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|x86.Build.0 = Release|Win32 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA}.Release|x86.Deploy.0 = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|AnyCPU.ActiveCfg = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|AnyCPU.Build.0 = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|AnyCPU.Deploy.0 = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|x64.ActiveCfg = Debug|x64 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|x64.Build.0 = Debug|x64 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|x86.ActiveCfg = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|x86.Build.0 = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Debug|x86.Deploy.0 = Debug|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|AnyCPU.ActiveCfg = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|AnyCPU.Build.0 = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|AnyCPU.Deploy.0 = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|x64.ActiveCfg = Release|x64 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|x64.Build.0 = Release|x64 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|x86.ActiveCfg = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|x86.Build.0 = Release|Win32 + {60E8E057-79E1-4860-A015-23C9587434F7}.Release|x86.Deploy.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CF85847B-E97C-4020-A8DC-AA3B46E42331} + EndGlobalSection +EndGlobal diff --git a/src/Microsoft.DotNet.Wpf/redist/VCRuntime/VCRuntime.vcxproj b/src/Microsoft.DotNet.Wpf/redist/VCRuntime/VCRuntime.vcxproj new file mode 100644 index 00000000000..34229aa58ca --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/redist/VCRuntime/VCRuntime.vcxproj @@ -0,0 +1,80 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + DynamicLibrary + false + + + + + + + + Microsoft.VC142.CRT + Microsoft.VC142.DebugCRT + + + Microsoft.VC141.CRT + Microsoft.VC141.DebugCRT + + + $(VCRuntimeDllBaseName)$(VCRuntimeVersion)$(LibSuffix)$(WpfVersionSuffix) + $(VCRuntimeDllBaseName)$(VCRuntimeVersion)$(LibSuffix) + + + + + + $(VCInstallDir)Redist\MSVC\$(VCToolsRedistVersion)\ + $(VCInstallDir)Redist\MSVC\$(VCToolsRedistVersion)\debug_nonredist\ + + $(VCRedistRoot)$(Architecture)\$(VCRedistCrtFolderName)\$(VCRuntimeDllBaseName)$(VCRuntimeVersion)$(LibSuffix).dll + $(VCRedistRoot)$(Architecture)\$(VCRedistFallbackCrtFolderName)\$(VCRuntimeDllBaseName)$(VCRuntimeVersion)$(LibSuffix).dll + + + + + + $(OutDir)$(MSVCPDllBaseName)$(MSVCPVersion)$(LibSuffix).dll + + + + $(OutDir)$(MSVCPDllBaseName)$(MSVCPVersion)$(LibSuffix).dll + + + + + 16.0 + {B7399B2E-CE92-42D5-B36A-EBD4C9C4FBDA} + Win32Proj + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dir.targets b/src/Microsoft.DotNet.Wpf/src/PenImc/dir.targets new file mode 100644 index 00000000000..5236e7c6faf --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dir.targets @@ -0,0 +1,3 @@ + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComApartmentVerifier.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComApartmentVerifier.cpp new file mode 100644 index 00000000000..5a754446d3d --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComApartmentVerifier.cpp @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +#include "stdafx.h" + +#include "ComApartmentVerifier.hpp" + +using namespace ComUtils; + +ComApartmentVerifier::ComApartmentVerifier() + : m_valid(false) +{ +} + +ComApartmentVerifier ComApartmentVerifier::Mta() +{ + // MTA is free threaded. + return ComApartmentVerifier(APTTYPE::APTTYPE_MTA); +} + +ComApartmentVerifier ComApartmentVerifier::CurrentSta() +{ + APTTYPE aptType; + APTTYPEQUALIFIER aptQualifier; + + HRESULT hr = CoGetApartmentType(&aptType, &aptQualifier); + + if (hr != S_OK || (aptType != APTTYPE::APTTYPE_STA && aptType != APTTYPE::APTTYPE_MAINSTA)) + { + return ComApartmentVerifier(); + } + + // For STA, ensure we use the current thread and that the current apartment type matches. + // This is so we capture the COM thread/apartment state at creation to use later. + return ComApartmentVerifier(aptType, ::GetCurrentThreadId()); +} + +HRESULT ComApartmentVerifier::VerifyCurrentApartmentType() +{ + HRESULT hr = RPC_E_WRONG_THREAD; + + if (m_valid) + { + APTTYPE aptType; + APTTYPEQUALIFIER aptQualifier; + + HRESULT aptHr = CoGetApartmentType(&aptType, &aptQualifier); + + if (aptHr == S_OK + && aptType == m_expectedApartment + && (!m_expectedApartmentIsSta || m_expectedStaThreadId == ::GetCurrentThreadId())) + { + hr = S_OK; + } + } + + return hr; +} + + +ComApartmentVerifier::ComApartmentVerifier(APTTYPE aptType) : + m_expectedApartment(aptType), + m_expectedApartmentIsSta(false), + m_expectedStaThreadId(0), + m_valid(m_expectedApartment != APTTYPE::APTTYPE_STA && m_expectedApartment != APTTYPE::APTTYPE_MAINSTA) +{ + // We only verify STA/MAINSTA via a thread id constructor. +} + +ComApartmentVerifier::ComApartmentVerifier(APTTYPE aptType, DWORD threadId) : + m_expectedApartment(aptType), + m_expectedApartmentIsSta(true), + m_expectedStaThreadId(threadId), + m_valid(m_expectedApartment == APTTYPE::APTTYPE_STA || m_expectedApartment == APTTYPE::APTTYPE_MAINSTA) +{ + // Don't use a thread id constructor for any other apartment types but STA/MAINSTA. +} + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComApartmentVerifier.hpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComApartmentVerifier.hpp new file mode 100644 index 00000000000..4b89a22b374 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComApartmentVerifier.hpp @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +#pragma once + +#include + +namespace ComUtils +{ + // DDVSO:514949 + // This class provides functionality for checking and verifying apartment state. + class ComApartmentVerifier + { + public: + + // Default constructor, sets an invalid state. + ComApartmentVerifier(); + + // Returns a verifier for MTA + static ComApartmentVerifier Mta(); + + // Returns a verifier for the current STA. + // NOTE: This verifier includes the current thread id in verification. + static ComApartmentVerifier CurrentSta(); + + // Verifies the current apartment and, if applicable, thread id. + HRESULT VerifyCurrentApartmentType(); + + private: + + // Constructor for apartment type, free threaded. + ComApartmentVerifier(APTTYPE); + + // Constructor for apartment type, specific thread. + ComApartmentVerifier(APTTYPE, DWORD); + + // The COM apartment type to expect. + APTTYPE m_expectedApartment; + + // If the apartment type is STA. + bool m_expectedApartmentIsSta; + + // The id of the thread to expect. + DWORD m_expectedStaThreadId; + + // Determines if this is in a valid (non-default constructed, appropriate arguments) state. + bool m_valid; + }; +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComLockableWrapper.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComLockableWrapper.cpp new file mode 100644 index 00000000000..7e76166c0bd --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComLockableWrapper.cpp @@ -0,0 +1,87 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +#include "stdafx.h" + +#include "ComApartmentVerifier.hpp" +#include "ComLockableWrapper.hpp" + +using namespace ComUtils; + +ComLockableWrapper::ComLockableWrapper() + : m_serverObject(nullptr), + m_expectedApartment(ComApartmentVerifier()) + +{ +} + +ComLockableWrapper::ComLockableWrapper(IUnknown *obj, ComApartmentVerifier expectedApartment) + : m_serverObject(obj), + m_expectedApartment(expectedApartment) +{ +} + +HRESULT ComLockableWrapper::Lock() +{ + HRESULT hr = m_expectedApartment.VerifyCurrentApartmentType(); + + if (SUCCEEDED(hr)) + { + hr = E_ILLEGAL_METHOD_CALL; + + if (m_serverObject != nullptr) + { + IUnknown *unk = nullptr; + hr = m_serverObject->QueryInterface(IID_IUnknown, reinterpret_cast(&unk)); + + if (SUCCEEDED(hr)) + { + hr = CoLockObjectExternal(unk, + true, // fLock + false); // fLastUnlockReleases - unused + + unk->Release(); + } + } + } + + return hr; +} + +HRESULT ComLockableWrapper::Unlock() +{ + HRESULT hr = m_expectedApartment.VerifyCurrentApartmentType(); + + if (SUCCEEDED(hr)) + { + hr = E_ILLEGAL_METHOD_CALL; + + if (m_serverObject != nullptr) + { + IUnknown *unk = nullptr; + hr = m_serverObject->QueryInterface(IID_IUnknown, reinterpret_cast(&unk)); + + if (SUCCEEDED(hr)) + { + hr = CoLockObjectExternal(unk, + false, // fLock + true); // fLastUnlockReleases + + // The QI AddRefs, so balance it + unk->Release(); + + // This lock is one shot, do not allow further operations. + m_serverObject = nullptr; + } + } + } + + return hr; +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComLockableWrapper.hpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComLockableWrapper.hpp new file mode 100644 index 00000000000..b16aae55806 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/ComLockableWrapper.hpp @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +#pragma once + +#include "ComApartmentVerifier.hpp" + +namespace ComUtils +{ + // DDVSO:514949 + // This class provides functionality used for various methods of + // working around the COM rundown issues present in the OS (see OSGVSO:10779198). + // The purpose is to call CoLockObjectExternal on a server object to ensure that + // none of the COM hierarchy of the object is released during rundown. + // NOTE: + // Unlocking makes this object invalid. The server object is set to nullptr. + // Using this after unlocking will not succeed. + class ComLockableWrapper + { + public: + + // Default constructor, wraps a nullptr + ComLockableWrapper(); + + // Wraps a pointer with specific apartment type + // Requires manual locking/unlocking. + ComLockableWrapper(IUnknown *obj, ComApartmentVerifier expectedApartment); + + // Attempts to lock the server object via CoLockObjectExternal. + // The apartment is verified during this call. + HRESULT Lock(); + + // Attempts to unlock the server object via CoLockObjectExternal. + // The apartment is verified during this call. + HRESULT Unlock(); + + private: + + IUnknown *m_serverObject; + ComApartmentVerifier m_expectedApartment; + }; +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/GitComLockableWrapper.hpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/GitComLockableWrapper.hpp new file mode 100644 index 00000000000..18481694fee --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/GitComLockableWrapper.hpp @@ -0,0 +1,158 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ + +#pragma once + +#include "ComLockableWrapper.hpp" +#include "ComApartmentVerifier.hpp" + +namespace ComUtils +{ + // DDVSO:514949 + // This class provides functionality used for various methods of + // working around the COM rundown issues present in the OS (see OSGVSO:10779198). + // The purpose is to obtain an object from the GIT and then use ComLockableWrapper + // to ensure the object obtained survives rundown. + // NOTE: + // Unlocking makes this object invalid.The GIT pointer is set to nullptr. + // Using this after unlocking will not succeed. + template + class GitComLockableWrapper + { + public: + + // Default constructor, wraps a nullptr + GitComLockableWrapper(); + + // COM object constructor. + // Inserts the COM object into the GIT and stores the key. + GitComLockableWrapper(CComPtr obj, ComApartmentVerifier expectedApartment); + + // GIT key constructor. + // Stores the key for later use in other operations. + GitComLockableWrapper(DWORD gitKey, ComApartmentVerifier expectedApartment); + + // Attempts to Lock the object by querying it from the GIT + // and then using ComLockableWrapper. + // Apartment is verified during this call. + HRESULT Lock(); + + // Attempts to Unlock the object by querying it from the GIT + // and then using ComLockableWrapper. + // Apartment is verified during this call. + HRESULT Unlock(); + + // Returns the GIT cookie that refers to this wrapped object in the GIT. + DWORD GetCookie() const { return m_gitKey; } + + // Retrieves the wrapped object from the GIT. + CComPtr GetComObject(); + + // Revokes the wrapped object from the GIT if the cookie is valid. + // Otherwise this is a no_op. + void RevokeIfValid(); + + // Checks the validity of the GIT Cookie. + HRESULT CheckCookie() { return (m_gitKey != 0) ? S_OK : E_FAIL; }; + + private: + + DWORD m_gitKey; + ComApartmentVerifier m_expectedApartment; + }; + + template + GitComLockableWrapper::GitComLockableWrapper() + : m_gitKey(0), + m_expectedApartment(ComApartmentVerifier()) + { + } + + template + GitComLockableWrapper::GitComLockableWrapper(CComPtr obj, ComApartmentVerifier expectedApartment) + : m_expectedApartment(expectedApartment) + { + CComGITPtr git(obj); + m_gitKey = git.Detach(); + } + + template + GitComLockableWrapper::GitComLockableWrapper(DWORD gitKey, ComApartmentVerifier expectedApartment) + : m_gitKey(gitKey), + m_expectedApartment(expectedApartment) + { + } + + template + CComPtr GitComLockableWrapper::GetComObject() + { + CComPtr result = nullptr; + + if (m_gitKey != 0) + { + T *instance = nullptr; + + CComGITPtr git(m_gitKey); + HRESULT hr = git.CopyTo(&instance); + git.Detach(); + + if (SUCCEEDED(hr)) + { + result = instance; + instance->Release(); + } + } + + return result; + } + + template + HRESULT GitComLockableWrapper::Lock() + { + HRESULT hr = E_FAIL; + + CComPtr obj = GetComObject(); + + if (obj != nullptr) + { + ComLockableWrapper wrapper(obj, m_expectedApartment); + hr = wrapper.Lock(); + } + + return hr; + } + + template + HRESULT GitComLockableWrapper::Unlock() + { + HRESULT hr = E_FAIL; + + CComPtr obj = GetComObject(); + + if (obj != nullptr) + { + ComLockableWrapper wrapper(obj, m_expectedApartment); + hr = wrapper.Unlock(); + } + + return hr; + } + + template + void GitComLockableWrapper::RevokeIfValid() + { + if (SUCCEEDED(CheckCookie())) + { + CComGITPtr git(m_gitKey); + git.Revoke(); + } + } +} + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbList.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbList.cpp new file mode 100644 index 00000000000..a83c5e759a9 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbList.cpp @@ -0,0 +1,250 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +#include "StdAfx.h" +#include "PbList.h" + +///////////////////////////////////////////////////////////////////////////// + +#ifdef DBG +void AssertSizeOfList(CPbList * pList, INT cExpected) +{ + ASSERT(0 <= cExpected); + ASSERT(0 == cExpected && pList->IsEmpty() || + 0 < cExpected && !pList->IsEmpty()); + + // a sample enumeration forward + + PBLKEY key = pList->GetHead(); + INT cActualF = 0; + while (!pList->IsAtEnd(key)) + { + cActualF++; + key = pList->GetNext(key); + } + + // a sample enumeration backwards + + key = pList->GetTail(); + INT cActualB = 0; + while (!pList->IsAtEnd(key)) + { + cActualB++; + key = pList->GetPrev(key); + } + + // assert + + ASSERT (cActualF == cExpected); + ASSERT (cActualB == cExpected); +} + +void TestPbList() +{ + DHR; + PBLKEY key = PBLKEY_NULL; + CPbList list; + + // still empty + ASSERT (list.IsEmpty()); + + // add item 1 + CHR_VERIFY(list.AddToTail(&key)); + list[key] = 1; + AssertSizeOfList(&list, 1); + key = list.GetHead(); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // add item 2 + CHR_VERIFY(list.AddToTail(&key)); + list[key] = 2; + AssertSizeOfList(&list, 2); + key = list.GetHead(); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list[key] == 2); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // add item 3 + CHR_VERIFY(list.AddToTail(&key)); + list[key] = 3; + AssertSizeOfList(&list, 3); + key = list.GetHead(); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list[key] == 2); + key = list.GetNext(key); + ASSERT (list[key] == 3); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // add item 4, to head + CHR_VERIFY(list.AddToHead(&key)); + list[key] = 4; + AssertSizeOfList(&list, 4); + key = list.GetHead(); + ASSERT (list[key] == 4); + key = list.GetNext(key); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list[key] == 2); + key = list.GetNext(key); + ASSERT (list[key] == 3); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // delete the head item + key = list.GetHead(); + CHR_VERIFY(list.Remove(key)); + AssertSizeOfList(&list, 3); + key = list.GetHead(); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list[key] == 2); + key = list.GetNext(key); + ASSERT (list[key] == 3); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // delete the tail item + key = list.GetTail(); + CHR_VERIFY(list.Remove(key)); + AssertSizeOfList(&list, 2); + key = list.GetHead(); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list[key] == 2); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // delete the tail item again + key = list.GetTail(); + CHR_VERIFY(list.Remove(key)); + AssertSizeOfList(&list, 1); + key = list.GetHead(); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // delete the last remaining item + key = list.GetHead(); + CHR_VERIFY(list.Remove(key)); + AssertSizeOfList(&list, 0); + ASSERT (list.IsEmpty()); + + // populate a bigger list (reversed in order) + AssertSizeOfList(&list, 0); + CHR_VERIFY(list.AddToHead(&key)); + list[key] = 1; + AssertSizeOfList(&list, 1); + CHR_VERIFY(list.AddToHead(&key)); + list[key] = 2; + AssertSizeOfList(&list, 2); + CHR_VERIFY(list.AddToHead(&key)); + list[key] = 3; + AssertSizeOfList(&list, 3); + CHR_VERIFY(list.AddToHead(&key)); + list[key] = 4; + AssertSizeOfList(&list, 4); + CHR_VERIFY(list.AddToHead(&key)); + list[key] = 5; + AssertSizeOfList(&list, 5); + + // delete from the middle + key = list.GetHead(); + key = list.GetNext(key); + key = list.GetNext(key); + CHR_VERIFY(list.Remove(key)); + AssertSizeOfList(&list, 4); + key = list.GetHead(); + ASSERT (list[key] == 5); + key = list.GetNext(key); + ASSERT (list[key] == 4); + key = list.GetNext(key); + ASSERT (list[key] == 2); + key = list.GetNext(key); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // move last item to front + key = list.GetTail(); + CHR_VERIFY(list.MoveToHead(key)); + AssertSizeOfList(&list, 4); + key = list.GetHead(); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list[key] == 5); + key = list.GetNext(key); + ASSERT (list[key] == 4); + key = list.GetNext(key); + ASSERT (list[key] == 2); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // move second item to back + key = list.GetHead(); + key = list.GetNext(key); + CHR_VERIFY(list.MoveToTail(key)); + AssertSizeOfList(&list, 4); + key = list.GetHead(); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list[key] == 4); + key = list.GetNext(key); + ASSERT (list[key] == 2); + key = list.GetNext(key); + ASSERT (list[key] == 5); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // insert an item to head + CHR_VERIFY(list.InsertBefore(list.GetHead(), &key)); + list[key] = 3; + AssertSizeOfList(&list, 5); + key = list.GetHead(); + ASSERT (list[key] == 3); + key = list.GetNext(key); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list[key] == 4); + key = list.GetNext(key); + ASSERT (list[key] == 2); + key = list.GetNext(key); + ASSERT (list[key] == 5); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + + // insert an item in the middle + key = list.GetHead(); + key = list.GetNext(key); + key = list.GetNext(key); + CHR_VERIFY(list.InsertBefore(key, &key)); + list[key] = 6; + AssertSizeOfList(&list, 6); + key = list.GetHead(); + ASSERT (list[key] == 3); + key = list.GetNext(key); + ASSERT (list[key] == 1); + key = list.GetNext(key); + ASSERT (list[key] == 6); + key = list.GetNext(key); + ASSERT (list[key] == 4); + key = list.GetNext(key); + ASSERT (list[key] == 2); + key = list.GetNext(key); + ASSERT (list[key] == 5); + key = list.GetNext(key); + ASSERT (list.IsAtEnd(key)); + +CLEANUP: + return; +} +#endif + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbList.h b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbList.h new file mode 100644 index 00000000000..7503fb7a5fc --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbList.h @@ -0,0 +1,392 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +#pragma once + +///////////////////////////////////////////////////////////////////////////// + +typedef DWORD_PTR PBLKEY; // PBList KEY + +#define PBLKEY_NULL NULL + +///////////////////////////////////////////////////////////////////////////// + +template +class CPbList +{ +public: + + ///////////////////////////////////////////////////////////////////////// + + CPbList() + { + m_pHead = NULL; + m_pTail = NULL; +#ifdef DBG + m_pfSyncCheckDbg = NULL; +#endif + } + + ///////////////////////////////////////////////////////////////////////// + + ~CPbList() + { + ClearList(); + } + + ///////////////////////////////////////////////////////////////////////// + +#ifdef DBG + void SetSyncCheckDbg(BOOL * pfSyncCheckDbg) + { + m_pfSyncCheckDbg = pfSyncCheckDbg; + } +#endif + + ///////////////////////////////////////////////////////////////////////// + +#ifdef DBG + BOOL SyncCheckDbg() + { + if (!m_pfSyncCheckDbg) + return TRUE; + return SyncCheckCoreDbg(*m_pfSyncCheckDbg); + } +#endif + + ///////////////////////////////////////////////////////////////////////// + +#ifdef DBG + static BOOL SyncCheckCoreDbg(BOOL fSyncCheckDbg) + { + return fSyncCheckDbg; + } +#endif + + ///////////////////////////////////////////////////////////////////////// + + HRESULT AddToHead(ENTRY_TYPE entry) + { + DHR; + PBLKEY key; + CHR(AddToHead(&key)); + (*this)[key] = entry; + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT AddToTail(ENTRY_TYPE entry) + { + DHR; + PBLKEY key; + CHR(AddToTail(&key)); + (*this)[key] = entry; + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT AddToHead(__typefix(CListEntry *) __out PBLKEY * pkeyNew) + { + DHR; + ASSERT (SyncCheckDbg()); + ASSERT (pkeyNew); + CListEntry * pNew = new CListEntry; + CHR_MEMALLOC(pNew); + CHR(AddToHeadCore(pNew)) + *pkeyNew = (PBLKEY)pNew; + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT AddToTail(__typefix(CListEntry *) __out PBLKEY * pkeyNew) + { + DHR; + ASSERT (SyncCheckDbg()); + ASSERT (pkeyNew); + CListEntry * pNew = new CListEntry; + CHR_MEMALLOC(pNew); + CHR(AddToTailCore(pNew)) + *pkeyNew = (PBLKEY)pNew; + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT InsertBefore(__typefix(CListEntry *) __inout PBLKEY keyBefore, __typefix(CListEntry *) __out PBLKEY * pkeyNew) + { + DHR; + ASSERT (SyncCheckDbg()); + ASSERT (pkeyNew); + CListEntry * pNew = new CListEntry; + CHR_MEMALLOC(pNew); + CHR(InsertBeforeCore(keyBefore, pNew)) + *pkeyNew = (PBLKEY)pNew; + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT Remove(__typefix(CListEntry *) __in PBLKEY key, bool deleteEntry) + { + DHR; + ASSERT (SyncCheckDbg()); + ASSERT (!IsAtEnd(key)); + CListEntry * p = (CListEntry*)key; + CHR(RemoveCore(p)); + + if (deleteEntry) + { + delete p; + } + + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT MoveToHead(__typefix(CListEntry *) __inout PBLKEY key) + { + DHR; + ASSERT (SyncCheckDbg()); + ASSERT (!IsAtEnd(key)); + CListEntry * p = (CListEntry*)key; + CHR(RemoveCore(p)); + CHR(AddToHeadCore(p)); + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT MoveToTail(__typefix(CListEntry *) __inout PBLKEY key) + { + DHR; + ASSERT (SyncCheckDbg()); + ASSERT (!IsAtEnd(key)); + CListEntry * p = (CListEntry*)key; + CHR(RemoveCore(p)); + CHR(AddToTailCore(p)); + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + inline __typefix(CListEntry *) __out PBLKEY GetHead() + { + ASSERT (SyncCheckDbg()); + return (PBLKEY)m_pHead; + } + + ///////////////////////////////////////////////////////////////////////// + + inline __typefix(CListEntry *) __out PBLKEY GetTail() + { + ASSERT (SyncCheckDbg()); + return (PBLKEY)m_pTail; + } + + ///////////////////////////////////////////////////////////////////////// + + inline __typefix(CListEntry *) __out PBLKEY GetNext(__typefix(CListEntry *) __in PBLKEY key) + { + ASSERT (SyncCheckDbg()); + ASSERT (!IsAtEnd(key)); + CListEntry * p = (CListEntry*)key; + return (PBLKEY)p->m_pNext; + } + + ///////////////////////////////////////////////////////////////////////// + + inline __typefix(CListEntry *) __out PBLKEY GetPrev(__typefix(CListEntry *) __in PBLKEY key) + { + ASSERT (SyncCheckDbg()); + ASSERT (!IsAtEnd(key)); + CListEntry * p = (CListEntry*)key; + return (PBLKEY)p->m_pPrev; + } + + ///////////////////////////////////////////////////////////////////////// + + inline __out ENTRY_TYPE & operator[](__typefix(CListEntry *) __in PBLKEY key) + { + ASSERT (SyncCheckDbg()); + return Entry(key); + } + + ///////////////////////////////////////////////////////////////////////// + + inline static __out ENTRY_TYPE & Entry( + __typefix(CListEntry *) __in PBLKEY key +#ifdef DBG + , BOOL fSyncCheckDbg = TRUE +#endif + ) + { + ASSERT (SyncCheckCoreDbg(fSyncCheckDbg)); + CListEntry * p = (CListEntry*)key; + return p->m_data; + } + + ///////////////////////////////////////////////////////////////////////// + + inline BOOL IsAtEnd(__typefix(CListEntry *) __in PBLKEY key) + { + ASSERT (SyncCheckDbg()); + return key == NULL; + } + + ///////////////////////////////////////////////////////////////////////// + + inline BOOL IsEmpty() + { + ASSERT (SyncCheckDbg()); + return m_pHead == NULL; + } + + ///////////////////////////////////////////////////////////////////////// + +protected: + + ///////////////////////////////////////////////////////////////////////// + + class CListEntry + { + public: + ENTRY_TYPE m_data; + CListEntry * m_pPrev; + CListEntry * m_pNext; + }; + + ///////////////////////////////////////////////////////////////////////// + + void ClearList() + { + CListEntry * pCur = m_pHead; + while (pCur) + { + CListEntry * pToDel = pCur; + pCur = pCur->m_pNext; + delete pToDel; + } + m_pHead = m_pTail = NULL; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT AddToHeadCore(__inout CListEntry * pNew) + { + DHR; + + if (!m_pTail) + m_pTail = pNew; + + pNew->m_pPrev = NULL; + pNew->m_pNext = m_pHead; + + if (m_pHead) + m_pHead->m_pPrev = pNew; + + m_pHead = pNew; + + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT AddToTailCore(__inout CListEntry * pNew) + { + DHR; + + if (!m_pHead) + m_pHead = pNew; + + pNew->m_pPrev = m_pTail; + pNew->m_pNext = NULL; + + if (m_pTail) + m_pTail->m_pNext = pNew; + + m_pTail = pNew; + + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT InsertBeforeCore(__typefix(CListEntry *) __inout PBLKEY keyBefore, __inout CListEntry * pNew) + { + DHR; + + ASSERT(pNew); + + CListEntry * pPoint = (CListEntry*)keyBefore; + CListEntry * pPrev = pPoint->m_pPrev; + + if (pPrev) + pPrev->m_pNext = pNew; + else + m_pHead = pNew; + + pPoint->m_pPrev = pNew; + + pNew->m_pPrev = pPrev; + pNew->m_pNext = pPoint; + + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT RemoveCore (__in CListEntry * p) + { + DHR; + + ASSERT (p); + + CListEntry * pPrev = p->m_pPrev; + CListEntry * pNext = p->m_pNext; + if (pPrev) + pPrev->m_pNext = pNext; + if (pNext) + pNext->m_pPrev = pPrev; + + if (m_pHead == p) + m_pHead = pNext; + if (m_pTail == p) + m_pTail = pPrev; + + ASSERT (m_pHead != p); + ASSERT (m_pTail != p); + + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + CListEntry * m_pHead; + CListEntry * m_pTail; + +#ifdef DBG + BOOL * m_pfSyncCheckDbg; +#endif +}; // class CPbList + +///////////////////////////////////////////////////////////////////////////// + +#ifdef DBG +void TestPbList(); +#endif + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbPreallocArray.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbPreallocArray.cpp new file mode 100644 index 00000000000..5654eda0daa --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbPreallocArray.cpp @@ -0,0 +1,162 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +#pragma once + +///////////////////////////////////////////////////////////////////////////// + +template +class CPbPreallocArray +{ +public: + + ///////////////////////////////////////////////////////////////////////// + + CPbPreallocArray() + { + m_cCurrent = 0; + m_cAllocated = INITIAL_COUNT; + m_pa = m_aInitial; + }; + + ///////////////////////////////////////////////////////////////////////// + + ~CPbPreallocArray() + { + if (m_pa != NULL && + m_pa != m_aInitial) + { + delete m_pa; + } + }; + + ///////////////////////////////////////////////////////////////////////// + + inline INT GetSize() + { + return m_cCurrent; + }; + + ///////////////////////////////////////////////////////////////////////// + + HRESULT SetSize(INT cNew, BOOL fGrowFast = TRUE) + { + DHR; + + CHR(EnsureSize(cNew, fGrowFast)); + + m_cCurrent = cNew; + + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT Add(INT * pidxNew, BOOL fGrowFast = TRUE) + { + DHR; + ASSERT (pidxNew); + CHR(SetSize(GetSize() + 1, fGrowFast)); + *pidxNew = GetSize() - 1; + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT Add(ENTRY_TYPE entry, BOOL fGrowFast = TRUE) + { + DHR; + INT idxNew; + CHR(Add(&idxNew)); + (*this)[idxNew] = entry; + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + ENTRY_TYPE & operator[](UINT idx) + { + ASSERT (idx < m_cCurrent); + return m_pa[idx]; + } + + ///////////////////////////////////////////////////////////////////////// + + ENTRY_TYPE * GetData() + { + ASSERT (m_pa); + return m_pa; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT Remove(UINT idx) + { + DHR; + ASSERT (0 <= idx && idx < m_cCurrent); + if (idx < m_cCurrent - 1) + { + UINT cbToCopy = sizeof(m_pa[0]) * (m_cCurrent - idx - 1); + ASSERT (sizeof(m_pa[0]) * 1 <= cbToCopy && cbToCopy <= sizeof(m_pa[0]) * (m_cCurrent - 1)); + CopyMemory(&(m_pa[idx]), &(m_pa[idx + 1]), cbToCopy); + } + m_cCurrent--; + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + +protected: + + ///////////////////////////////////////////////////////////////////////// + + HRESULT EnsureSize(UINT cRequested, BOOL fGrowFast) + { + DHR; + + if (m_cAllocated < cRequested) + { + if (fGrowFast) + cRequested = max(m_cAllocated * 2, cRequested); + + ASSERT (m_pa != NULL); + if (m_pa == m_aInitial) + { + CHR_MEMALLOC(m_pa = new ENTRY_TYPE[cRequested]); + CopyMemory(m_pa, m_aInitial, sizeof(m_pa[0]) * m_cAllocated); + } + else + { + ENTRY_TYPE * paNew = (ENTRY_TYPE*)realloc(m_pa, sizeof(m_pa[0]) * cRequested); + CHR_MEMALLOC(paNew); + m_pa = paNew; + } + m_cAllocated = cRequested; + } + + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + +protected: + + ENTRY_TYPE m_aInitial[INITIAL_COUNT]; + ENTRY_TYPE* m_pa; + UINT m_cAllocated; + UINT m_cCurrent; +}; + +///////////////////////////////////////////////////////////////////////////// + +#ifdef DBG +void TestPbPreallocArray(); +#endif + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbPreallocArray.h b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbPreallocArray.h new file mode 100644 index 00000000000..0718fdde35e --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PbPreallocArray.h @@ -0,0 +1,166 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +#pragma once + +///////////////////////////////////////////////////////////////////////////// + +template +class CPbPreallocArray +{ +public: + + ///////////////////////////////////////////////////////////////////////// + + CPbPreallocArray() + { + m_cCurrent = 0; + m_cAllocated = INITIAL_COUNT; + m_pa = m_aInitial; + }; + + ///////////////////////////////////////////////////////////////////////// + + ~CPbPreallocArray() + { + if (m_pa != NULL && + m_pa != m_aInitial) + { + delete m_pa; + } + }; + + ///////////////////////////////////////////////////////////////////////// + + inline INT GetSize() + { + return m_cCurrent; + }; + + ///////////////////////////////////////////////////////////////////////// + + HRESULT SetSize(INT cNew, BOOL fGrowFast = TRUE) + { + DHR; + + CHR(EnsureSize(cNew, fGrowFast)); + + m_cCurrent = cNew; + + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT Add(__out INT * pidxNew, BOOL fGrowFast = TRUE) + { + DHR; + ASSERT (pidxNew); + // Make sure we don't overflow UINT (GetSize() + 1 < MAXINT). If we do handle as out of memory error. + CHR_MEMALLOC(GetSize() < (~(UINT)0) ? 1 /*not NULL*/ : NULL); + CHR(SetSize(GetSize() + 1, fGrowFast)); + *pidxNew = GetSize() - 1; + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT Add(ENTRY_TYPE entry, BOOL fGrowFast = TRUE) + { + DHR; + INT idxNew; + CHR(Add(&idxNew)); + (*this)[idxNew] = entry; + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + + __out ENTRY_TYPE & operator[](UINT idx) + { + ASSERT (idx < m_cCurrent); + return m_pa[idx]; + } + + ///////////////////////////////////////////////////////////////////////// + + __out ENTRY_TYPE * GetData() + { + ASSERT (m_pa); + return m_pa; + } + + ///////////////////////////////////////////////////////////////////////// + + HRESULT Remove(UINT idx) + { + DHR; + ASSERT (0 <= idx && idx < m_cCurrent); + if (idx < m_cCurrent - 1) + { + UINT cbToCopy = sizeof(m_pa[0]) * (m_cCurrent - idx - 1); + ASSERT (sizeof(m_pa[0]) * 1 <= cbToCopy && cbToCopy <= sizeof(m_pa[0]) * (m_cCurrent - 1)); + CopyMemory(&(m_pa[idx]), &(m_pa[idx + 1]), cbToCopy); + } + m_cCurrent--; + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + +protected: + + ///////////////////////////////////////////////////////////////////////// + + HRESULT EnsureSize(UINT cRequested, BOOL fGrowFast) + { + DHR; + + if (m_cAllocated < cRequested) + { + if (fGrowFast) + cRequested = max(m_cAllocated * 2, cRequested); + + ASSERT (m_pa != NULL); + // Make sure we don't overflow byte count (cRequested * sizeof(ENTRY_TYPE)). If we do handle as out of memory error. + CHR_MEMALLOC(cRequested <= ((~(UINT)0) / (sizeof(ENTRY_TYPE))) ? 1 /*not NULL*/ : NULL); + if (m_pa == m_aInitial) + { + CHR_MEMALLOC(m_pa = new ENTRY_TYPE[cRequested]); + CopyMemory(m_pa, m_aInitial, sizeof(m_pa[0]) * m_cAllocated); + } + else + { + ENTRY_TYPE * paNew = (ENTRY_TYPE*)realloc(m_pa, sizeof(m_pa[0]) * cRequested); + CHR_MEMALLOC(paNew); + m_pa = paNew; + } + m_cAllocated = cRequested; + } + + CLEANUP: + RHR; + } + + ///////////////////////////////////////////////////////////////////////// + +protected: + + ENTRY_TYPE m_aInitial[INITIAL_COUNT]; + ENTRY_TYPE* m_pa; + UINT m_cAllocated; + UINT m_cCurrent; +}; + +///////////////////////////////////////////////////////////////////////////// + +#ifdef DBG +void TestPbPreallocArray(); +#endif + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenIMC.manifest b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenIMC.manifest new file mode 100644 index 00000000000..076c130ad46 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenIMC.manifest @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.cpp new file mode 100644 index 00000000000..37ef3140bbd --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.cpp @@ -0,0 +1,218 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// PenImc.cpp : Implementation of DLL Exports. + +#include "stdafx.h" +#include "resource.h" +#include "PenImc.h" +#include "PimcManager.h" + +#include +#include "dlldatax.h" +#include "penimc_i.c" +#include +#include +#include +//#include + + +#if 1 // from tablib.lib WIP (toddt) this is to be fixed after the new build changes settle down. +void SafeCloseHandle(__inout HANDLE * pHandle) +{ + ASSERT (pHandle); + + if (*pHandle) + { + CloseHandle(*pHandle); + *pHandle = NULL; + } +} +#endif + +///////////////////////////////////////////////////////////////////////////// + +class CPenImcModule : public CAtlDllModuleT< CPenImcModule > +{ +public : + DECLARE_LIBID(LIBID_PenImcLib4v3) + DECLARE_REGISTRY_APPID_RESOURCEID(IDR_PENIMC, "{E31B1A40-9FE5-46D8-98F0-9B0F75F0320C}") +}; + +CPenImcModule _AtlModule; + +///////////////////////////////////////////////////////////////////////////// + +#if WANT_SINGLETON +class CPimcManagerFactory : public IClassFactory +{ +public: + STDMETHOD_(ULONG, AddRef) () { return 1; } + STDMETHOD_(ULONG, Release)() { return 1; }; + STDMETHOD(QueryInterface)(REFIID riid, void** ppv); + STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObject); + STDMETHOD(LockServer)(BOOL fLock); +}; + +CPimcManagerFactory _PimcManagerFactory; +#endif // WANT_SINGLETON + +///////////////////////////////////////////////////////////////////////////// + +extern "C" BOOL WINAPI DllMain(__in HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hMutexHook = CreateMutex(NULL, /* initial ownership */FALSE, NULL); + //Assert g_hMutexHook != null? + } + else if (dwReason == DLL_PROCESS_DETACH) + { + //ASSERT(g_cHookLock == 0); + SafeCloseHandle(&g_hMutexHook); + } + +#ifdef _MERGE_PROXYSTUB + if (!PrxDllMain(hInstance, dwReason, lpReserved)) + return FALSE; +#endif + hInstance; + return _AtlModule.DllMain(dwReason, lpReserved); +} + +///////////////////////////////////////////////////////////////////////////// + +__control_entrypoint(DllExport) +STDAPI DllCanUnloadNow(void) +{ +#ifdef _MERGE_PROXYSTUB + HRESULT hr = PrxDllCanUnloadNow(); + if (hr != S_OK) + return hr; +#endif + return _AtlModule.DllCanUnloadNow(); +} + + +///////////////////////////////////////////////////////////////////////////// + +_Check_return_ +STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID* ppv) +{ +#ifdef _MERGE_PROXYSTUB + HRESULT hr = PrxDllGetClassObject(rclsid, riid, ppv); + if (hr != CLASS_E_CLASSNOTAVAILABLE) + return hr; +#endif + + // NOTE: + // In order to support multiple app domains we don't want to return just one + // object for both those app domains or we cause problems with the RPC interface + // we have to wisptis. We need to actually create two different CPimcManager + // objects in order to run properly. This required the removal of the singleton + // support below. Since the avalon stylus code uses a static class to manage + // the CPimcManager object we will only get one instance per app domain which is + // what we want. + +#if WANT_SINGLETON + // This is how we implement PimcManager as a singleton. We could've used + // DECLARE_CLASSFACTORY_SINGLETON, but in that case PimcManager gets released + // way too late because _AtlModule is holding refs on it until destructor. + // In that case PimcManager thread gets killed rather than experiencing a normal + // shutdown. + if (IsEqualGUID(rclsid, CLSID_PimcManager)) + { + return _PimcManagerFactory.QueryInterface(riid, ppv); + } +#endif + + return _AtlModule.DllGetClassObject(rclsid, riid, ppv); +} + + +///////////////////////////////////////////////////////////////////////////// + +__control_entrypoint(DllExport) +STDAPI DllRegisterServer(void) +{ + // registers object, typelib and all interfaces in typelib + HRESULT hr = _AtlModule.DllRegisterServer(); +#ifdef _MERGE_PROXYSTUB + if (FAILED(hr)) + return hr; + hr = PrxDllRegisterServer(); +#endif + return hr; +} + + +///////////////////////////////////////////////////////////////////////////// + +__control_entrypoint(DllExport) +STDAPI DllUnregisterServer(void) +{ + HRESULT hr = _AtlModule.DllUnregisterServer(); +#ifdef _MERGE_PROXYSTUB + if (FAILED(hr)) + return hr; + hr = PrxDllRegisterServer(); + if (FAILED(hr)) + return hr; + hr = PrxDllUnregisterServer(); +#endif + return hr; +} + + +#if WANT_SINGLETON + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcManagerFactory::QueryInterface(REFIID riid, __typefix(IClassFactory **) __deref_out void** ppv) +{ + DHR; + if (IsEqualGUID(riid, IID_IUnknown) || + IsEqualGUID(riid, IID_IClassFactory)) + { + *ppv = (IClassFactory*)this; + AddRef(); + CHR(S_OK); + } + else + { + CHR(E_NOINTERFACE); + } +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcManagerFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, __deref_out LPVOID * ppvObject) +{ + DHR; + if (Mgr() == NULL) + { + CComObject * pMgr; + CHR(CComObject::CreateInstance(&pMgr)); + } + ASSERT(Mgr() != NULL); + CHR(Mgr()->QueryInterface(riid, (void**)ppvObject)); +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcManagerFactory::LockServer(BOOL fLock) +{ + if (fLock) + _AtlModule.Lock(); + else + _AtlModule.Unlock(); + return S_OK; +} +#endif // WANT_SINGLETON + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.def b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.def new file mode 100644 index 00000000000..193a703c902 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.def @@ -0,0 +1,25 @@ +; Licensed to the .NET Foundation under one or more agreements. +; The .NET Foundation licenses this file to you under the MIT license. +; See the LICENSE file in the project root for more information. + + +; PenImc.def : Declares the module parameters. + +LIBRARY DLL_NAME + +EXPORTS + GetProxyDllInfo PRIVATE + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + GetPenEvent PRIVATE + GetPenEventMultiple PRIVATE + CreateResetEvent PRIVATE + DestroyResetEvent PRIVATE + RaiseResetEvent PRIVATE + GetLastSystemEventData PRIVATE + LockWispObjectFromGit PRIVATE + UnlockWispObjectFromGit PRIVATE + RegisterDllForSxSCOM PRIVATE + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.idl b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.idl new file mode 100644 index 00000000000..9c31e52c420 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.idl @@ -0,0 +1,123 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// PenImc.idl : IDL source for PenImc +// + +// This file will be processed by the MIDL tool to +// produce the type library (PenImc.tlb) and marshalling code. + +import "oaidl.idl"; +import "ocidl.idl"; + +[ + object, + uuid(75C6AAEE-2BA4-4008-B523-4F1E033FF049), + nonextensible, + helpstring("IPimcContext3 Interface"), + pointer_default(unique) +] +interface IPimcContext3 : IUnknown{ + [helpstring("method ShutdownComm") ] HRESULT ShutdownComm(); + [helpstring("method GetPacketDescriptionInfo") ] HRESULT GetPacketDescriptionInfo([out] INT * pcProps, [out] INT * pcButtons); + [helpstring("method GetPacketPropertyInfo") ] HRESULT GetPacketPropertyInfo([in] INT iProp, [out] GUID * pGuid, [out] INT * piMin, [out] INT * piMax, [out] INT * piUnits, [out] FLOAT *pflResolution); + [helpstring("method GetPacketButtonInfo") ] HRESULT GetPacketButtonInfo([in] INT iButton, [out] GUID * pGuid); + [helpstring("method GetLastSystemEventData") ] HRESULT GetLastSystemEventData([out] INT * piEvent, [out] INT * piModifier, [out] INT * piKey, [out] INT * piX, [out] INT * piY, [out] INT * piCursorMode, [out] INT * piButtonState); +}; + +[ + object, + uuid(CEB1EF24-BB4E-498B-9DF7-12887ED0EB24), + nonextensible, + helpstring("IPimcTablet3 Interface"), + pointer_default(unique) +] +interface IPimcTablet3 : IUnknown{ + [helpstring("method GetKey") ] HRESULT GetKey ([out] INT * pKey); + [helpstring("method GetName") ] HRESULT GetName ([out] LPWSTR * ppszName); + [helpstring("method GetPlugAndPlayId") ] HRESULT GetPlugAndPlayId ([out] LPWSTR * ppszPlugAndPlayId); + [helpstring("method GetTabletAndDisplaySize")] HRESULT GetTabletAndDisplaySize ([out] INT * piTabletWidth, [out] INT * piTabletHeight, [out] INT * piDisplayWidth, [out] INT * piDisplayHeight); + [helpstring("method GetHardwareCaps") ] HRESULT GetHardwareCaps ([out] INT * piCaps); + [helpstring("method GetDeviceType") ] HRESULT GetDeviceType ([out] INT * piDevType); + [helpstring("method RefreshCursorInfo") ] HRESULT RefreshCursorInfo (); + [helpstring("method GetCursorCount") ] HRESULT GetCursorCount ([out] INT * pcCursors); + [helpstring("method GetCursorInfo") ] HRESULT GetCursorInfo ([in] INT iCursor, [out] LPWSTR * ppszName, [out] INT * pId, [out] BOOL * pfInverted); + [helpstring("method GetCursorButtonCount") ] HRESULT GetCursorButtonCount ([in] INT iCursor, [out] INT * pcButtons); + [helpstring("method GetCursorButtonInfo") ] HRESULT GetCursorButtonInfo ([in] INT iCursor, [in] INT iButton, [out] LPWSTR * ppszName, [out] GUID * pGuid); + [helpstring("method IsPropertySupported") ] HRESULT IsPropertySupported ([in] GUID guid, [out] BOOL * pfSupported); + [helpstring("method GetPropertyInfo") ] HRESULT GetPropertyInfo ([in] GUID guid, [out] INT * piMin, [out] INT * piMax, [out] INT * piUnit, [out] FLOAT *pflResolution); + [helpstring("method CreateContext")] HRESULT CreateContext([in] INT_PTR hwnd, [in]BOOL fEnable, [in]UINT timeout, [out]IPimcContext3** ppCtx, [out] INT * pKey, [out] hyper * pHandle); + [helpstring("method GetPacketDescriptionInfo") ] HRESULT GetPacketDescriptionInfo([out] INT * pcProps, [out] INT * pcButtons); + [helpstring("method GetPacketPropertyInfo") ] HRESULT GetPacketPropertyInfo([in] INT iProp, [out] GUID * pGuid, [out] INT * piMin, [out] INT * piMax, [out] INT * piUnits, [out] FLOAT *pflResolution); + [helpstring("method GetPacketButtonInfo") ] HRESULT GetPacketButtonInfo([in] INT iButton, [out] GUID * pGuid); +}; + +[ + object, + uuid(BD2C38C2-E064-41D0-A999-940F526219C2), + nonextensible, + helpstring("IPimcManager3 Interface"), + pointer_default(unique) +] +interface IPimcManager3 : IUnknown { + [helpstring("method GetTabletCount")] HRESULT GetTabletCount([out] ULONG* pcTablets); + [helpstring("method GetTablet") ] HRESULT GetTablet([in] ULONG iTablet, [out] IPimcTablet3** ppTablet); +}; + +[ + object, + uuid(74D2B283-EDB3-4A8D-8088-445E8766C872), + nonextensible, + helpstring("IPimcSurrogate3 Interface"), + pointer_default(unique) +] +interface IPimcSurrogate3 : IUnknown { + [helpstring("method GetWisptisITabletManager")] HRESULT GetWisptisITabletManager([out] IUnknown** ppTabletManagerUnknown); +}; + +[ + uuid(33363EEE-828A-4DFC-BB3C-AB9628E6DD62), + version(2.0), + helpstring("PenIMC v4 2.0 Type Library") +] +library PenImcLib4v3 +{ + importlib("stdole2.tlb"); + + [ + uuid(F269D7C4-EF22-48A1-A503-4E0A620FC746), + helpstring("PimcSurrogate3 Class") + ] + coclass PimcSurrogate3 + { + [default] interface IPimcSurrogate3; + }; + + [ + uuid(DB88ADFD-BEC7-47B8-A6B5-58CA3DA2B8D6), + helpstring("PimcManager3 Class") + ] + coclass PimcManager3 + { + [default] interface IPimcManager3; + }; + [ + uuid(A50E4FEE-6A0C-4AD6-8FDE-8E3EC75956BF), + helpstring("PimcContext3 Class") + ] + coclass PimcContext3 + { + [default] interface IPimcContext3; + }; + [ + uuid(8E44D1B9-D701-4E65-9917-0FF7488A7F96), + helpstring("PimcTablet3 Class") + ] + coclass PimcTablet3 + { + [default] interface IPimcTablet3; + }; +}; + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.rc b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.rc new file mode 100644 index 00000000000..8a769cd3e86 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.rc @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#define FX_VER_FILEDESCRIPTION_STR "Microsoft Tablet PC Component" + +#include +#include "resource.h" +#include + +///////////////////////////////////////////////////////////////////////////// +// +// SxS Manifest +// + +ISOLATIONAWARE_MANIFEST_RESOURCE_ID RT_MANIFEST "PenIMC.manifest" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_PROJNAME "PenImc" +END + +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +1 TYPELIB "PenImc.tlb" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.sln b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.sln new file mode 100644 index 00000000000..8c479c18359 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28407.52 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OSVersionHelper", "..\..\Shared\OSVersionHelper\OSVersionHelper.vcxproj", "{3801B5AE-6871-4A72-B400-1F6ABCBF9045}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TabLib", "..\tablib\TabLib.vcxproj", "{8F91EB3A-C530-4CEA-90BF-AFC8165B6456}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PenImc", "PenImc.vcxproj", "{8383C663-E8D0-4D2D-B65A-FE4A253E3319}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3801B5AE-6871-4A72-B400-1F6ABCBF9045}.Debug|x64.ActiveCfg = Debug|x64 + {3801B5AE-6871-4A72-B400-1F6ABCBF9045}.Debug|x64.Build.0 = Debug|x64 + {3801B5AE-6871-4A72-B400-1F6ABCBF9045}.Debug|x86.ActiveCfg = Debug|Win32 + {3801B5AE-6871-4A72-B400-1F6ABCBF9045}.Debug|x86.Build.0 = Debug|Win32 + {3801B5AE-6871-4A72-B400-1F6ABCBF9045}.Release|x64.ActiveCfg = Release|x64 + {3801B5AE-6871-4A72-B400-1F6ABCBF9045}.Release|x64.Build.0 = Release|x64 + {3801B5AE-6871-4A72-B400-1F6ABCBF9045}.Release|x86.ActiveCfg = Release|Win32 + {3801B5AE-6871-4A72-B400-1F6ABCBF9045}.Release|x86.Build.0 = Release|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|x64.ActiveCfg = Debug|x64 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|x64.Build.0 = Debug|x64 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|x86.ActiveCfg = Debug|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Debug|x86.Build.0 = Debug|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|x64.ActiveCfg = Release|x64 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|x64.Build.0 = Release|x64 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|x86.ActiveCfg = Release|Win32 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456}.Release|x86.Build.0 = Release|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|x64.ActiveCfg = Debug|x64 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|x64.Build.0 = Debug|x64 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|x86.ActiveCfg = Debug|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Debug|x86.Build.0 = Debug|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|x64.ActiveCfg = Release|x64 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|x64.Build.0 = Release|x64 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|x86.ActiveCfg = Release|Win32 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7D57B352-EBB6-4244-9548-0346D749EE47} + EndGlobalSection +EndGlobal diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.vcxproj b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.vcxproj new file mode 100644 index 00000000000..8fb2f95f1ad --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PenImc.vcxproj @@ -0,0 +1,99 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + false + DynamicLibrary + + + + + + + + + CompileAsC + NotUsing + + + + + + + + + + + + Create + + + PenImc.h + true + $(IntermediateOutputPath) + + + + + + + + + 15.0 + {8383C663-E8D0-4D2D-B65A-FE4A253E3319} + Win32Proj + PenImc$(WpfVersionSuffix) + PenImc$(WpfVersionSuffix) + $(PreProcessorDefinitions);_MERGE_PROXYSTUB;_USRDLL + false + + + + + Use + true + _MERGE_PROXYSTUB;_USRDLL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories);$(WpfSourceDir)PenImc\inc\;$(IntermediateOutputPath) + + + $(IntermediateOutputPath)PenImc.i + %(AdditionalDependencies);kernel32.lib;advapi32.lib;uuid.lib;ole32.lib;oleaut32.lib;user32.lib;shlwapi.lib;rpcrt4.lib;rpcns4.lib;shell32.lib + + + + + + {8f91eb3a-c530-4cea-90bf-afc8165b6456} + + + {3801B5AE-6871-4A72-B400-1F6ABCBF9045} + + + + + + $(MSBuildThisFileDirectory)PenImc.def + PenImc.i + + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcContext.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcContext.cpp new file mode 100644 index 00000000000..9578b17934e --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcContext.cpp @@ -0,0 +1,1107 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// PimcContext.cpp : Implementation of CPimcContext + +#include "stdafx.h" + +#include "ComApartmentVerifier.hpp" +#include "pblist.h" +#include "PimcContext.h" +#include "..\tablib\sidutils.h" +#include "..\tablib\scopes.h" + +using namespace ComUtils; + +///////////////////////////////////////////////////////////////////////////// +// +// NOTE (alexz) There are several key assumptions used here to simplify this code. +// Should the assumptions change, the code may break in a subtle +// way. This includes data corruption due to missing synchronization, etc. +// Look for ASSUMPTION markers for more details. +// + +///////////////////////////////////////////////////////////////////////////// +// CPimcContext + +///////////////////////////////////////////////////////////////////////////// + +CPimcContext::CPimcContext() : + m_sink(new CEventSink()), m_hEventMoreData(NULL), m_hEventClientReady(NULL), + m_hMutexSharedMemory(NULL), m_hFileMappingSharedMemory(NULL), + m_pSharedMemoryHeader(NULL), m_pbSharedMemoryRawData(NULL), + m_cHandles(0), m_pHandles(NULL), m_cbPackets(0), + m_pbPackets(NULL), m_fCommHandleOutstanding(FALSE), + m_pMgr(NULL), m_pPacketDescription(NULL), m_hEventUpdate(NULL), m_fIsTopmostHook(FALSE) +{ +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::Init( + __inout CComPtr pMgr, + __in_opt CComPtr pCtxS, + __in HWND hwnd, + TABLET_CONTEXT_ID tcid, + PACKET_DESCRIPTION * pPacketDescription) +{ + DHR; + // Make sure we clean up properly on failures. + bool fCleanupCritSection = false; + bool fCleanupHook = false; + bool fCleanupCtx = false; + + m_pMgr = pMgr; + + if (pCtxS) + { + // DDVSO:289954 + // We need to store the ITabletContextP inside the COM Global Interface Table + // (GIT) because the proxy we get here from the QueryInterface will not be + // valid when used within the ExecuteUpdates function. Using the GIT ensures + // that we get an appropriate proxy when the time comes. + CHR(pCtxS->QueryInterface(IID_ITabletContextP, reinterpret_cast(&m_pCtxS))); + m_wispContextLock = GitComLockableWrapper(m_pCtxS, ComApartmentVerifier::Mta()); + CHR(m_wispContextLock.CheckCookie()); + + fCleanupCtx = true; + + m_fIsTopmostHook = (m_pCtxS->IsTopMostHook() == S_OK); + } + + m_tcid = tcid; + m_pPacketDescription = pPacketDescription; + + m_dwUpdatesPending = 0; + InitializeCriticalSection(&m_csUpdates); + fCleanupCritSection = true; + m_hEventUpdate = CreateEvent(NULL, FALSE, FALSE, NULL); + CHR(m_hEventUpdate ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_CREATEEVENT_CALL)); + + CHR(m_pMgr->InstallWindowHook(hwnd, this)); + fCleanupHook = true; + + if (pCtxS) + { + CComPtr pCtxP; + CHR(m_pCtxS->QueryInterface(IID_ITabletContextP, (void**)&pCtxP)); + + hr = InitUnnamedCommunications(pCtxP); + + // NOTICE-2006/05/25-WAYNEZEN, + // The named communications is supported by wisptis on Vista ONLY. + if ( hr == E_ACCESSDENIED && m_pMgr->IsVistaOrGreater() ) + { + hr = InitNamedCommunications(pCtxP); + } + + CHR(hr); + } + + m_fSingleFireTimeout = FALSE; + m_dwSingleFireTimeout = INFINITE; + + RHR; + +CLEANUP: + // On failure, make sure we clean up things. + if (fCleanupHook) + m_pMgr->UninstallWindowHook(this); + if (fCleanupCritSection) + DeleteCriticalSection(&m_csUpdates); + SafeCloseHandle(&m_hEventUpdate); + + if (fCleanupCtx) + m_wispContextLock.RevokeIfValid(); + + m_pMgr = NULL; + + m_pPacketDescription = NULL; + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +void CPimcContext::FinalRelease() +{ + if (m_pMgr != NULL) + { + m_pMgr->UninstallWindowHook(this); + + ShutdownSharedMemoryCommunications(); + + if (m_pPacketDescription) + { + DestroyPacketDescription(m_pPacketDescription); + m_pPacketDescription = NULL; + } + + DeleteCriticalSection(&m_csUpdates); + SafeCloseHandle(&m_hEventUpdate); + + m_wispContextLock.RevokeIfValid(); + + m_pMgr = NULL; + } +} + +/////////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::InitUnnamedCommunications(__in CComPtr pCtxP) +{ + DHR; + + CHR(pCtxP->UseSharedMemoryCommunications( + GetCurrentProcessId(), + (DWORD*)&m_hEventMoreData, + (DWORD*)&m_hEventClientReady, + (DWORD*)&m_hMutexSharedMemory, + (DWORD*)&m_hFileMappingSharedMemory)); + CHR(InitCommunicationsCore()); + +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::InitNamedCommunications(__in CComPtr pCtxP) +{ + DHR; + + DWORD dwPid = GetCurrentProcessId(); + DWORD dwMoreDataEventId; + DWORD dwClientReadyEventId; + DWORD dwSharedMemoryMutexId; + DWORD dwFileMappingId; + + ScopedLocalString pszSid; + ScopedLocalString pszSidIntegrity; + + ASSERTSZ(m_pMgr->IsVistaOrGreater(), _T("Only Vista supports the named communications.")); + + CHR(GetUserSid(&pszSid.get())); + CHR(GetMandatoryLabel(&pszSidIntegrity.get())); + + CHR(pCtxP->UseNamedSharedMemoryCommunications( + dwPid, + pszSid, + pszSidIntegrity, + &dwMoreDataEventId, + &dwClientReadyEventId, + &dwSharedMemoryMutexId, + &dwFileMappingId)); + + TCHAR szMoreDataName[MAX_PATH + 1]; + TCHAR szMutexName[MAX_PATH + 1]; + TCHAR szSectionName[MAX_PATH + 1]; + TCHAR szClientReadyName[MAX_PATH + 1]; + + StringCchPrintf( + szMoreDataName, + LENGTHOFARRAY(szMoreDataName), + WISPTIS_SM_MORE_DATA_EVENT_NAME, + dwPid, + dwMoreDataEventId); + + StringCchPrintf( + szMutexName, + LENGTHOFARRAY(szMutexName), + WISPTIS_SM_MUTEX_NAME, + dwPid, + dwSharedMemoryMutexId); + + StringCchPrintf( + szSectionName, + LENGTHOFARRAY(szSectionName), + WISPTIS_SM_SECTION_NAME, + dwPid, + dwFileMappingId); + + StringCchPrintf( + szClientReadyName, + LENGTHOFARRAY(szClientReadyName), + WISPTIS_SM_THREAD_EVENT_NAME, + dwClientReadyEventId); + + m_hEventClientReady = OpenEvent(EVENT_ALL_ACCESS, FALSE, szClientReadyName); + CHR_WIN32(m_hEventClientReady); + + m_hEventMoreData = OpenEvent(SYNCHRONIZE, FALSE, szMoreDataName); + CHR_WIN32(m_hEventMoreData); + + m_hMutexSharedMemory = OpenMutex(MUTEX_ALL_ACCESS, FALSE, szMutexName); + CHR_WIN32(m_hMutexSharedMemory); + + m_hFileMappingSharedMemory = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, szSectionName); + CHR_WIN32(m_hFileMappingSharedMemory); + + CHR(InitCommunicationsCore()); + + CLEANUP: + if(FAILED(hr)) + { + SafeCloseHandle(&m_hFileMappingSharedMemory); + SafeCloseHandle(&m_hMutexSharedMemory); + SafeCloseHandle(&m_hEventMoreData); + SafeCloseHandle(&m_hEventClientReady); + } + + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::InitCommunicationsCore() +{ + DHR; + + CHR(m_hEventMoreData && m_hEventClientReady && m_hMutexSharedMemory && m_hFileMappingSharedMemory ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_USESHAREDMEMORYCOM_CALL)); + + m_pSharedMemoryHeader = (SHAREDMEMORY_HEADER*)MapViewOfFile( + m_hFileMappingSharedMemory, // handle + FILE_MAP_READ | FILE_MAP_WRITE, // desired access + 0, // offset in file, High + 0, // offset in file, Low + sizeof(SHAREDMEMORY_HEADER)); // number of bytes to map + CHR(m_pSharedMemoryHeader ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_SHAREDMEMORYHEADER_NULL)); + +#pragma prefast( suppress: 11, "Dereferencing NULL pointer 'm_pSharedMemoryHeader'." ) + m_pbSharedMemoryRawData = (BYTE*)MapViewOfFile( + m_hFileMappingSharedMemory, // handle + FILE_MAP_READ, // desired access + 0, // offset in file, High + 0, // offset in file, Low + m_pSharedMemoryHeader->cbTotal);// number of bytes to map + CHR(m_pbSharedMemoryRawData ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_SHAREDMEMORYRAWDATA_NULL)); + + m_pbSharedMemoryPackets = m_pbSharedMemoryRawData + sizeof(SHAREDMEMORY_HEADER); + + m_cHandles = 0; + m_pHandles = NULL; + m_cbPackets = 0; + m_pbPackets = NULL; + m_fCommHandleOutstanding = FALSE; + +CLEANUP: + if (FAILED(hr)) + ShutdownSharedMemoryCommunications(); + + RHR; +} + +/////////////////////////////////////////////////////////////////////////////// + +void CPimcContext::ShutdownSharedMemoryCommunications() +{ + if (m_pSharedMemoryHeader) + { + UnmapViewOfFile(m_pSharedMemoryHeader); + m_pSharedMemoryHeader = NULL; + } + if (m_pbSharedMemoryRawData) + { + UnmapViewOfFile(m_pbSharedMemoryRawData); + m_pbSharedMemoryRawData = NULL; + } + + SafeCloseHandle(&m_hEventMoreData); + SafeCloseHandle(&m_hEventClientReady); + SafeCloseHandle(&m_hMutexSharedMemory); + SafeCloseHandle(&m_hFileMappingSharedMemory); + if (m_pHandles) + { + delete [] m_pHandles; + m_pHandles = NULL; + } + if (m_pbPackets) + { + delete [] m_pbPackets; + m_pbPackets = NULL; + } +} + +/////////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::GetCommHandle(__out INT64* pHandle) +{ + // ASSUMPTION (alexz) this call is always balanced by ShutdownComm + // (responsibility of the caller) + DHR; + CHR(pHandle ? S_OK : E_INVALIDARG); + + if (m_wispContextLock.GetCookie() != 0) + { + ASSERT (!m_fCommHandleOutstanding); + CHR(!m_fCommHandleOutstanding ? S_OK : E_UNEXPECTED); + m_fCommHandleOutstanding = TRUE; + *pHandle = (INT_PTR)this; + + // DDVSO:514949 + // Create the CPimcContext and CEventSink lock here since we know this object is fully instantiated (including IUnknown). + m_contextLock = ComLockableWrapper(this, ComApartmentVerifier::CurrentSta()); + m_sinkLock = ComLockableWrapper(m_sink.p, ComApartmentVerifier::CurrentSta()); + + // DDVSO:514949 + // Make sure that we increase the ref count here since we + // need to ensure that the apartment where this object lives + // stays alive. + AddRef(); + + // DDVSO:514949 + // Calling this ensures that the CStdIdentity for this object is + // not released if we hit a COM rundown due to OSGVSO:10779198. + CHR(m_contextLock.Lock()); + + // DDVSO:514949 + // Lock the CEventSink so WISP can rely on its proxy to it. + CHR(m_sinkLock.Lock()); + } + +CLEANUP: + RHR; +} + +/////////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcContext::ShutdownComm() +{ + DHR; + + if (m_wispContextLock.GetCookie() != 0) + { + ASSERT(m_fCommHandleOutstanding); + CHR (m_fCommHandleOutstanding ? S_OK : E_UNEXPECTED); + m_fCommHandleOutstanding = FALSE; + + // DDVSO:514949 + // Balance the call in Init. + CHR(m_sinkLock.Unlock()); + + // DDVSO:514949 + // Balance the call in GetCommHandle. + CHR(m_contextLock.Unlock()); + + // DDVSO:514949 + // Balance out any GetCommHandle call here. This will be done + // when the PenThread no longer is using this context. + Release(); + } + +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::GetKey(__out INT * pKey) +{ + DHR; + CHR(pKey ? S_OK : E_INVALIDARG); + *pKey = m_tcid; +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcContext::GetPacketDescriptionInfo(__out INT * pcProps, __out INT * pcButtons) +{ + DHR; + CHR(pcProps ? S_OK : E_INVALIDARG); + CHR(pcButtons ? S_OK : E_INVALIDARG); + *pcProps = m_pPacketDescription->cPacketProperties; + *pcButtons = m_pPacketDescription->cButtons; +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcContext::GetPacketPropertyInfo(INT iProp, __out GUID * pGuid, __out INT * piMin, __out INT * piMax, __out INT * piUnits, __out FLOAT *pflResolution) +{ + HRESULT hr = S_OK; + + switch (iProp) + { + case QUERY_WISP_CONTEXT_KEY: + { + if (nullptr == piMin) + { + hr = E_INVALIDARG; + } + else + { + *piMin = (INT)m_wispContextLock.GetCookie(); + } + } + break; + default: + { + hr = GetPacketPropertyInfoImpl(iProp, pGuid, piMin, piMax, piUnits, pflResolution); + } + } + + return hr; +} + +STDMETHODIMP CPimcContext::GetPacketPropertyInfoImpl(INT iProp, __out GUID * pGuid, __out INT * piMin, __out INT * piMax, __out INT * piUnits, __out FLOAT *pflResolution) +{ + PACKET_PROPERTY * pProp = nullptr; + DHR; + CHR(0 <= iProp && (DWORD)iProp < m_pPacketDescription->cPacketProperties ? S_OK : E_INVALIDARG); + CHR(pGuid ? S_OK : E_INVALIDARG); + CHR(piMin ? S_OK : E_INVALIDARG); + CHR(piMax ? S_OK : E_INVALIDARG); + CHR(piUnits ? S_OK : E_INVALIDARG); + CHR(pflResolution ? S_OK : E_INVALIDARG); + // iProp value is checked above, disable prefast signedness warnings +#pragma prefast(suppress: 37001 37002 37003) + pProp = &(m_pPacketDescription->pPacketProperties[iProp]); + *pGuid = pProp->guid; + *piMin = pProp->PropertyMetrics.nLogicalMin; + *piMax = pProp->PropertyMetrics.nLogicalMax; + *piUnits = pProp->PropertyMetrics.Units; + *pflResolution = pProp->PropertyMetrics.fResolution; +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcContext::GetPacketButtonInfo(INT iButton, __out GUID * pGuid) +{ + DHR; + CHR(0 <= iButton && (DWORD)iButton < m_pPacketDescription->cButtons ? S_OK : E_INVALIDARG); + CHR(pGuid ? S_OK : E_INVALIDARG); + // iButton value is checked above, disable prefast signedness warnings +#pragma prefast(suppress: 37001 37002 37003) + *pGuid = m_pPacketDescription->pguidButtons[iButton]; +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +void CPimcContext::DestroyPacketDescription(__in_opt PACKET_DESCRIPTION * pPacketDescription) +{ + if (pPacketDescription) + { + if (pPacketDescription->pPacketProperties) + CoTaskMemFree(pPacketDescription->pPacketProperties); + + if (pPacketDescription->pguidButtons) + CoTaskMemFree(pPacketDescription->pguidButtons); + + CoTaskMemFree(pPacketDescription); + } +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::EnsureHandlesArray(INT cHandles) +{ + DHR; + if (m_cHandles < cHandles) + { + if (m_pHandles) + delete [] m_pHandles; + m_cHandles = cHandles * 2; + CHR_MEMALLOC(m_pHandles = new HANDLE[m_cHandles]); + } +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::EnsurePackets(DWORD cb) +{ + DHR; + if (m_cbPackets < cb) + { + if (m_pbPackets) + delete [] m_pbPackets; + m_cbPackets = max(256, cb * 2); + CHR_MEMALLOC(m_pbPackets = new BYTE[m_cbPackets]); + } +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::PostUpdate(DWORD update) +{ + DHR; + EnterCriticalSection(&m_csUpdates); + m_dwUpdatesPending |= update; + LeaveCriticalSection(&m_csUpdates); + SetEvent(m_hEventUpdate); + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::ExecuteUpdates() +{ + DWORD dwUpdatesPending; + + EnterCriticalSection(&m_csUpdates); + dwUpdatesPending = m_dwUpdatesPending; + m_dwUpdatesPending = 0; + LeaveCriticalSection(&m_csUpdates); + + CComPtr pCtxS = nullptr; + + if (dwUpdatesPending) + { + // DDVSO:289954 + // Access the underlying WISP tablet context in order to properly respond to updates + pCtxS = m_wispContextLock.GetComObject(); + + if (pCtxS != nullptr) + { + // (order of these is important) + + if (dwUpdatesPending & UPDATE_SizeMove) // size, move + { + RECT rc; + pCtxS->TrackInputRect(&rc); + } + if (dwUpdatesPending & UPDATE_SendToBack) // send to back + { + // If we are in wisptis PREHOOK (IsTopMost==true) queue then we can't call the Overlap API. + if (!m_fIsTopmostHook) + { + TABLET_CONTEXT_ID tcidT; + pCtxS->Overlap(/*fTop*/FALSE, &tcidT); + } + } + if (dwUpdatesPending & UPDATE_SendToTop) // send to top + { + // If we are in wisptis PREHOOK (IsTopMost==true) queue then we can't call the Overlap API. + if (!m_fIsTopmostHook) + { + TABLET_CONTEXT_ID tcidT; + pCtxS->Overlap(/*fTop*/TRUE, &tcidT); + } + } + } + else + { + return E_INVALIDARG; + } + } + + return S_OK; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcContext::GetLastSystemEventData( + __out INT * piEvent, __out INT * piModifier, __out INT * piKey, + __out INT * piX, __out INT * piY, __out INT * piCursorMode, __out INT * piButtonState) +{ + DHR; + CHR(piEvent ? S_OK : E_INVALIDARG); + CHR(piModifier ? S_OK : E_INVALIDARG); + CHR(piKey ? S_OK : E_INVALIDARG); + CHR(piX ? S_OK : E_INVALIDARG); + CHR(piY ? S_OK : E_INVALIDARG); + CHR(piCursorMode ? S_OK : E_INVALIDARG); + CHR(piButtonState ? S_OK : E_INVALIDARG); + *piEvent = (INT)m_sysEvt; + *piModifier = (INT)m_sysEvtData.bModifier; + *piKey = (INT)m_sysEvtData.wKey; + *piX = (INT)m_sysEvtData.xPos; + *piY = (INT)m_sysEvtData.yPos; + *piCursorMode = (INT)m_sysEvtData.bCursorMode; + *piButtonState = (INT)m_sysEvtData.dwButtonState; +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::SetSingleFireTimeout(UINT uiTimeout) +{ + DHR; + CHR(1 <= uiTimeout ? S_OK : E_INVALIDARG); + m_dwSingleFireTimeout = uiTimeout; +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +#ifdef DELIVERY_PROFILING +void CPimcContext::ProfilePackets(BOOL fDown, BOOL fUp, int x, int y) +{ + LARGE_INTEGER counter; + QueryPerformanceCounter(&counter); + unsigned t = counter.LowPart & LONG_MAX; + + const int cMax = 5000; + static int cCur = 0; + static int xs[cMax]; + static int ys[cMax]; + static unsigned ts[cMax]; + + switch (fDown * 0x10 + fUp) + { + case 0x10: // down + cCur = 0; + // fall thru + + case 0x00: // packets + if (cCur < cMax) + { + xs [cCur] = x; + ys [cCur] = y; + ts [cCur] = t; + cCur++; + } + break; + + case 0x01: // up + { + FILE * pf = fopen("c:\\perf_penimc_strokeProfile_wait.xml", "a+"); + if (pf) + { + fwprintf(pf, L" \n", cCur); + + for (int i = 0; i < cCur; i++) + { + fwprintf(pf, + L" \n", + i, ts[i], xs[i], ys[i]); + } + + fwprintf(pf, L" \n"); + + fclose(pf); + } + } + break; + } +} +#endif // DELIVERY_PROFILING + +/////////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::GetPenEventCore( + DWORD dwWait, + __out BOOL * pfWaitAgain, + __out BOOL * pfShutdown, + __out INT * pEvt, __out INT * pCursorId, + __out INT * pcPackets, __out INT * pcbPacket, __out INT_PTR * pPackets) +{ + DHR; + + ASSERT (pfShutdown); + *pfShutdown = FALSE; + *pfWaitAgain = FALSE; + + switch (dwWait) + { + case WAIT_TIMEOUT: + m_fSingleFireTimeout = FALSE; // (only fire the timeout once before more data shows up) + *pEvt = 1; // timeout event + *pCursorId = 0; + *pcPackets = 0; + *pcbPacket = 0; + *pPackets = NULL; + break; + + case WAIT_OBJECT_0 + 0: // update + *pfWaitAgain = TRUE; + ExecuteUpdates(); + break; + + case WAIT_OBJECT_0 + 1: // more data + { + m_fSingleFireTimeout = TRUE; // (got more data, set up for the time out again) + + // obtain mutex on the data + DWORD dwWaitAccess = WaitForSingleObject(m_hMutexSharedMemory, INFINITE); + CHR(dwWaitAccess == WAIT_OBJECT_0 ? S_OK : E_FAIL); + + // get the data + switch (m_pSharedMemoryHeader->dwEvent) + { + case WM_TABLET_PACKET: + case WM_TABLET_CURSORDOWN: + case WM_TABLET_CURSORUP: + *pEvt = m_pSharedMemoryHeader->dwEvent; + *pCursorId = m_pSharedMemoryHeader->cid; + *pcPackets = m_pSharedMemoryHeader->cPackets; + *pcbPacket = m_pSharedMemoryHeader->cbPackets / m_pSharedMemoryHeader->cPackets; + CHR(EnsurePackets(m_pSharedMemoryHeader->cbPackets)); + CopyMemory(m_pbPackets, m_pbSharedMemoryPackets, m_pSharedMemoryHeader->cbPackets); + *pPackets = (INT_PTR)m_pbPackets; + +#ifdef DELIVERY_PROFILING + for (INT iPacket = 0; iPacket < *pcPackets; iPacket++) + { + INT iOffset = iPacket * (*pcbPacket) / sizeof(LONG); + switch (m_pSharedMemoryHeader->dwEvent) + { + case WM_TABLET_PACKET: ProfilePackets(/*fDown*/FALSE, /*fUp*/FALSE, ((LONG*)m_pbSharedMemoryPackets)[iOffset + 0], ((LONG*)m_pbSharedMemoryPackets)[iOffset + 1]); break; + case WM_TABLET_CURSORDOWN: ProfilePackets(/*fDown*/TRUE, /*fUp*/FALSE, ((LONG*)m_pbSharedMemoryPackets)[iOffset + 0], ((LONG*)m_pbSharedMemoryPackets)[iOffset + 1]); break; + case WM_TABLET_CURSORUP: ProfilePackets(/*fDown*/FALSE, /*fUp*/TRUE, ((LONG*)m_pbSharedMemoryPackets)[iOffset + 0], ((LONG*)m_pbSharedMemoryPackets)[iOffset + 1]); break; + } + } +#endif + break; + + case WM_TABLET_CURSORINRANGE: + case WM_TABLET_CURSOROUTOFRANGE: + *pEvt = m_pSharedMemoryHeader->dwEvent; + *pCursorId = m_pSharedMemoryHeader->cid; + *pcPackets = 0; + *pcbPacket = 0; + *pPackets = NULL; + break; + + case WM_TABLET_SYSTEMEVENT: + *pEvt = m_pSharedMemoryHeader->dwEvent; + *pCursorId = m_pSharedMemoryHeader->cid; + *pcPackets = 0; + *pcbPacket = 0; + *pPackets = NULL; + m_sysEvt = m_pSharedMemoryHeader->sysEvt; + m_sysEvtData = m_pSharedMemoryHeader->sysEvtData; + break; + + default: + *pEvt = 0; + *pCursorId = 0; + *pcPackets = 0; + *pcbPacket = 0; + *pPackets = NULL; + break; + } + + // release the mutex we holding and signal wisptis to put more data here + m_pSharedMemoryHeader->dwEvent = WISPTIS_SHAREDMEMORY_AVAILABLE; + ReleaseMutex(m_hMutexSharedMemory); + SetEvent(m_hEventClientReady); + } + break; + + case WAIT_OBJECT_0 + 2: // reset + *pfShutdown = TRUE; + break; + + default: // an error condition; just keep rolling + break; + } + +CLEANUP: + RHR; +} + +/////////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::GetPenEvent( + __in_opt HANDLE hEventReset, __out BOOL * pfShutdown, + __out INT * pEvt, __out INT * pCursorId, + __out INT * pcPackets, __out INT * pcbPacket, __out INT_PTR * pPackets) +{ + DHR; + DWORD cObjects = 2; + HANDLE ahObjects[3]; + ahObjects[0] = m_hEventUpdate; + ahObjects[1] = m_hEventMoreData; + if (hEventReset) + { + ahObjects[cObjects] = hEventReset; + cObjects++; + } + + for (;;) + { + DWORD dwTimeout = m_fSingleFireTimeout ? m_dwSingleFireTimeout : INFINITE; + DWORD dwWait = MsgWaitForMultipleObjectsEx(cObjects, ahObjects, dwTimeout, 0, MWMO_ALERTABLE); + + BOOL fWaitAgain = FALSE; + CHR(GetPenEventCore(dwWait, &fWaitAgain, pfShutdown, pEvt, pCursorId, pcPackets, pcbPacket, pPackets)); + if (!fWaitAgain) + break; + } + +CLEANUP: + RHR; +} + +/////////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcContext::GetPenEventMultiple( + INT cCtxs, __in_ecount(cCtxs) CPimcContext ** ppCtxs, + __in_opt HANDLE hEventReset, + __out BOOL * pfShutdown, + __out INT * piCtxEvt, + __out INT * pEvt, __out INT * pCursorId, + __out INT * pcPackets, __out INT * pcbPacket, __out INT_PTR * pPackets) +{ + DHR; + + ASSERT (pfShutdown); + *pfShutdown = FALSE; + + HANDLE * pHandles = NULL; + INT cHandles = 0; + BOOL fSingleFireTimeout = FALSE; + DWORD dwSingleFireTimeout = INFINITE; + INT cCtxEvents = 0; + CPimcContext ** ppCtxCur = NULL; + + // See if we have a special case where we don't have any real pen contexts + // and just created the pen thread to get the UIContext on the pen thread set + // up. In this case we only need to wait for the reset event. + if (cCtxs == 0) + { + cHandles = 1; + pHandles = &hEventReset; + //fSingleFireTimeout = true; + //dwSingleFireTimeout = 500; // check every 500ms to see if we should shut down. + } + else + { + ASSERT (cCtxs); + ASSERT (piCtxEvt); + + // build up the wait array + for (INT i = 0; i < cCtxs; i++) + { + CPimcContext * pCtxHandleArray = ppCtxs[i]; + + // Create handles array on the context only if it participates in the wait. + if (pCtxHandleArray != NULL && + pCtxHandleArray->m_hEventMoreData) + { + CHR(pCtxHandleArray->EnsureHandlesArray(2 * cCtxs + 1)); // ASSUMPTION (alexz) no context is invoked on 2 separate threads + // via GetPenEvent/GetPenEventMultiple, at the same time + pHandles = pCtxHandleArray->m_pHandles; + break; + } + } + + if (NULL == pHandles) + { + cHandles = 1; + pHandles = &hEventReset; + } + else + { + HANDLE * phCur = pHandles; + + ppCtxCur = ppCtxs; + for (INT i = 0; i < cCtxs; i++) + { + if ((*ppCtxCur) && (*ppCtxCur)->m_hEventMoreData) + { + *phCur = (*ppCtxCur)->m_hEventUpdate; + phCur++; + cHandles++; + + *phCur = (*ppCtxCur)->m_hEventMoreData; + phCur++; + cHandles++; + + fSingleFireTimeout |= (*ppCtxCur)->m_fSingleFireTimeout; + dwSingleFireTimeout = min (dwSingleFireTimeout, (*ppCtxCur)->m_dwSingleFireTimeout); + } + ppCtxCur++; + } + + cCtxEvents = cHandles; + if (hEventReset) + { + *phCur = hEventReset; + phCur++; + cHandles++; + } + } + } + + // do the wait + for (;;) + { + DWORD dwTimeout = fSingleFireTimeout ? dwSingleFireTimeout : INFINITE; + DWORD dwWait = MsgWaitForMultipleObjectsEx(cHandles, pHandles, dwTimeout, 0, MWMO_ALERTABLE); + BOOL fWaitAgain = FALSE; + // dispatch the result of wait + if (dwWait == WAIT_TIMEOUT) + { + // If we hit a timeout when we don't have any real contexts then just deal with it as a + // shutdown so we'll check to see if we should shut this thread down. + if (cCtxs == 0) + { + *pfShutdown = TRUE; + } + else + { + *piCtxEvt = 0; + *pEvt = 1; // timeout event + *pCursorId = 0; + *pcPackets = 0; + *pcbPacket = 0; + *pPackets = NULL; + ppCtxCur = ppCtxs; + for (INT i = 0; i < cCtxs; i++) + { + if ( (*ppCtxCur) != NULL ) + (*ppCtxCur)->m_fSingleFireTimeout = FALSE; // (only fire the timeout once before more data shows up) + + ppCtxCur++; + } + } + } + else if (dwWait < WAIT_OBJECT_0 + cCtxEvents) + { + // Either more data or update event for a context was + // signaled. Find it and call GetPenEventCore on it. + HANDLE signaledHandle = pHandles[dwWait]; + *piCtxEvt = -1; + for (INT i = 0; i < cCtxs; i++) + { + // Check if the signaled handle belongs to this context + CPimcContext * pCtxHandle = ppCtxs[i]; + if (pCtxHandle != NULL && + (pCtxHandle->m_hEventMoreData == signaledHandle || + pCtxHandle->m_hEventUpdate == signaledHandle)) + { + *piCtxEvt = i; + break; + } + } + ASSERT(*piCtxEvt != -1); + CPimcContext * pCtxEvt = ppCtxs[*piCtxEvt]; + dwWait = dwWait % 2; + CHR(pCtxEvt->GetPenEventCore(dwWait, &fWaitAgain, pfShutdown, pEvt, pCursorId, pcPackets, pcbPacket, pPackets)); + } + else if (WAIT_OBJECT_0 + cCtxEvents == dwWait) + { + // wait was reset + *pfShutdown = TRUE; + } + else + { + // an unexpected condition; ignore it + } + if (!fWaitAgain) + break; + } + +CLEANUP: + RHR; +} + +/////////////////////////////////////////////////////////////////////////////// + +extern "C" BOOL WINAPI GetPenEvent( + __typefix(CPimcContext *) __in INT_PTR commHandle, + __typefix(HANDLE) __in_opt INT_PTR commHandleReset, + __out INT * pEvt, __out INT * pCursorId, + __out INT * pcPackets, __out INT * pcbPacket, __out INT_PTR * pPackets) +{ + CPimcContext * pCtx = nullptr; + DHR; + BOOL fShutdown = TRUE; + CHR(commHandle && pEvt && pCursorId && pcPackets && pcbPacket && pPackets ? S_OK : E_INVALIDARG); + pCtx = (CPimcContext *)commHandle; + CHR(pCtx->GetPenEvent((HANDLE)commHandleReset, &fShutdown, pEvt, pCursorId, pcPackets, pcbPacket, pPackets)); + +CLEANUP: + return SUCCEEDED(hr) && !fShutdown; +} + +/////////////////////////////////////////////////////////////////////////////// + +extern "C" BOOL WINAPI GetPenEventMultiple( + INT cCommHandles, __typefix(CPimcContext **) __in_ecount(cCommHandles) INT_PTR * pCommHandles, + __typefix(HANDLE) __in_opt INT_PTR commHandleReset, + __out INT * piEvt, + __out INT * pEvt, __out INT * pCursorId, + __out INT * pcPackets, __out INT * pcbPacket, __out INT_PTR * pPackets) +{ + DHR; + BOOL fShutdown = TRUE; + + CHR (((cCommHandles == 0 && commHandleReset) || + (cCommHandles && pCommHandles && commHandleReset && + piEvt && pEvt && pCursorId && pcPackets && pcbPacket && pPackets)) ? + S_OK : E_INVALIDARG); + + CHR(CPimcContext::GetPenEventMultiple( + cCommHandles, (CPimcContext **)pCommHandles, + (HANDLE) commHandleReset, + &fShutdown, + piEvt, + pEvt, pCursorId, + pcPackets, pcbPacket, pPackets)); + +CLEANUP: + return SUCCEEDED(hr) && !fShutdown; +} + +/////////////////////////////////////////////////////////////////////////////// + +extern "C" BOOL WINAPI GetLastSystemEventData( + __typefix(CPimcContext *) __in INT_PTR commHandle, + __out INT * piEvent, __out INT * piModifier, __out INT * piKey, + __out INT * piX, __out INT * piY, __out INT * piCursorMode, __out INT * piButtonState) +{ + CPimcContext * pCtx = nullptr; + DHR; + CHR(piEvent && piModifier && piKey && piX && piY && piCursorMode && piButtonState ? S_OK : E_INVALIDARG); + pCtx = (CPimcContext *)commHandle; + CHR(pCtx->GetLastSystemEventData(piEvent, piModifier, piKey, piX, piY, piCursorMode, piButtonState)); +CLEANUP: + return SUCCEEDED(hr); +} + +/////////////////////////////////////////////////////////////////////////////// + +extern "C" BOOL WINAPI CreateResetEvent(__out INT_PTR * pCommHandleReset) +{ + HANDLE hEventReset = nullptr; + DHR; + CHR (pCommHandleReset ? S_OK : E_INVALIDARG); + hEventReset = CreateEvent(NULL, FALSE, FALSE, NULL); + CHR(hEventReset ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_CANNOTCREATERESETEVENT)); + *pCommHandleReset = (INT_PTR)hEventReset; +CLEANUP: + return SUCCEEDED(hr); +} + +/////////////////////////////////////////////////////////////////////////////// + +extern "C" BOOL WINAPI DestroyResetEvent(__typefix(HANDLE) __in INT_PTR commHandleReset) +{ + HANDLE hEventReset = nullptr; + DHR; + CHR (commHandleReset ? S_OK : E_INVALIDARG); + hEventReset = (HANDLE)commHandleReset; + CloseHandle(hEventReset); +CLEANUP: + return SUCCEEDED(hr); +} + +/////////////////////////////////////////////////////////////////////////////// + +extern "C" BOOL WINAPI RaiseResetEvent(__typefix(HANDLE) __in INT_PTR commHandleReset) +{ + HANDLE hEventReset = nullptr; + DHR; + CHR (commHandleReset ? S_OK : E_INVALIDARG); + hEventReset = (HANDLE)commHandleReset; + SetEvent(hEventReset); +CLEANUP: + return SUCCEEDED(hr); +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcContext.h b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcContext.h new file mode 100644 index 00000000000..baadedd8b42 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcContext.h @@ -0,0 +1,208 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// PimcContext.h : Declaration of the CPimcContext + +#pragma once +#include "resource.h" // main symbols + +#include "PenImc.h" +#include "PimcManager.h" +#include "ComLockableWrapper.hpp" +#include "GitComLockableWrapper.hpp" + +///////////////////////////////////////////////////////////////////////////// +// CPimcContext + +class ATL_NO_VTABLE CPimcContext : + public CComObjectRootEx, + public CComCoClass, + public IPimcContext3 +{ +public: + + ///////////////////////////////////////////////////////////////////////// + + CPimcContext(); + HRESULT FinalConstruct() { return S_OK; } ; + void FinalRelease(); + HRESULT Init(__inout CComPtr pMgr, + __in_opt CComPtr pCtxS, + __in HWND hwnd, + TABLET_CONTEXT_ID tcid, + PACKET_DESCRIPTION * pPacketDescription); + + HRESULT InitUnnamedCommunications(__in CComPtr pCtxP); + HRESULT InitNamedCommunications(__in CComPtr pCtxP); + HRESULT InitCommunicationsCore(); + + void ShutdownSharedMemoryCommunications(); + + HRESULT GetPenEvent (__in_opt HANDLE hEventReset, __out BOOL * pfShutdown, __out INT * pEvt, __out INT * pCursorId, __out INT * pcPackets, __out INT * pcbPacket, __out INT_PTR * pPackets); + HRESULT GetPenEventCore (DWORD dwWait, __out BOOL * pfWaitAgain, __out BOOL * pfShutdown, __out INT * pEvt, __out INT * pCursorId, __out INT * pcPackets, __out INT * pcbPacket, __out INT_PTR * pPackets); + + static HRESULT GetPenEventMultiple( + INT cCtxs, __in_ecount(cCtxs) CPimcContext ** ppCtxs, + __in_opt HANDLE hEventAbort, + __out BOOL * pfShutdown, + __out INT * piCtxEvt, + __out INT * pEvt, __out INT * pCursorId, + __out INT * pcPackets, __out INT * pcbPacket, __out INT_PTR * pPackets); + + STDMETHOD(ShutdownComm)(); + STDMETHOD(GetPacketDescriptionInfo)(__out INT * pcProps, __out INT * pcButtons); + STDMETHOD(GetPacketPropertyInfo)(INT iProp, __out GUID * pGuid, __out INT * piMin, __out INT * piMax, __out INT * piUnits, __out FLOAT *pflResolution); + STDMETHOD(GetPacketPropertyInfoImpl)(INT iProp, __out GUID * pGuid, __out INT * piMin, __out INT * piMax, __out INT * piUnits, __out FLOAT *pflResolution); + STDMETHOD(GetPacketButtonInfo)(INT iButton, __out GUID * pGuid); + STDMETHOD(GetLastSystemEventData)(__out INT * piEvent, __out INT * piModifier, __out INT * piKey, __out INT * piX, __out INT * piY, __out INT * piCursorMode, __out INT * piButtonState); + + HRESULT GetCommHandle(__out INT64* pHandle); + HRESULT GetKey(__out INT * pKey); + HRESULT SetSingleFireTimeout(UINT uiTimeout); + HRESULT EnsureHandlesArray(INT cHandles); + HRESULT EnsurePackets(DWORD cb); + static void DestroyPacketDescription(__in_opt PACKET_DESCRIPTION * pPacketDescription); + +#ifdef DELIVERY_PROFILING + void ProfilePackets(BOOL fDown, BOOL fUp, int x, int y); +#endif + + const static DWORD UPDATE_SizeMove = 0x01; + const static DWORD UPDATE_SendToTop = 0x02; + const static DWORD UPDATE_SendToBack = 0x04; + const static DWORD UPDATE_Enable = 0x08; + const static DWORD UPDATE_Disable = 0x10; + + HRESULT PostUpdate(DWORD update); + HRESULT ExecuteUpdates(); + + ///////////////////////////////////////////////////////////////////////// + +BEGIN_COM_MAP(CPimcContext) + COM_INTERFACE_ENTRY(IPimcContext3) +END_COM_MAP() + + DECLARE_PROTECT_FINAL_CONSTRUCT() + + ///////////////////////////////////////////////////////////////////////// + + class CEventSink : public ITabletEventSink + { + public: + + // DDVSO:514949 + // The lifetime of this object needs to be correctly tracked via + // its IUnknown implementation as this will be passed onto WISP + // when a WISP context is created. WISP stores this in a CComPtr + // member variable and this object must be alive when the WISP + // context accesses it, even if the enclosing CPimcContext is + // already destroyed. + CEventSink() : m_cRef(0) + { + } + + // IUnknown + STDMETHOD(QueryInterface)(REFIID riid, __typefix(ITabletEventSink **) __deref_out_opt void** ppv) + { + DHR; + if (IsEqualGUID(riid, IID_IUnknown) || + IsEqualGUID(riid, IID_ITabletEventSink)) + { + *ppv = (ITabletEventSink*)this; + AddRef(); + hr = S_OK; + } + else + { + *ppv = NULL; + hr = E_NOINTERFACE; + } + RHR; + } + + STDMETHOD_(ULONG, AddRef) () + { + LONG newRefCount = InterlockedIncrement(&m_cRef); + return static_cast(newRefCount); + } + + STDMETHOD_(ULONG, Release)() + { + LONG newRefCount = InterlockedDecrement(&m_cRef); + + // We should fail immediately if the ref count is ever below 0. + // We want to know, even in production, if we have any unbalanced releases. + ATLASSERT(newRefCount >= 0); + + if (newRefCount == 0) + { + delete this; + } + + return static_cast(newRefCount); + } + + LONG m_cRef; + + // ITabletEventSink + STDMETHOD(ContextCreate) (TABLET_CONTEXT_ID tcid) { return S_OK; } + STDMETHOD(ContextDestroy) (TABLET_CONTEXT_ID tcid) { return S_OK; } + STDMETHOD(CursorNew) (TABLET_CONTEXT_ID tcid, CURSOR_ID cid) { return S_OK; } + STDMETHOD(CursorInRange) (TABLET_CONTEXT_ID tcid, CURSOR_ID cid) { return S_OK; } + STDMETHOD(CursorOutOfRange) (TABLET_CONTEXT_ID tcid, CURSOR_ID cid) { return S_OK; } + STDMETHOD(CursorMove) (TABLET_CONTEXT_ID tcid, CURSOR_ID cid, HWND hWnd, LONG xPos, LONG yPos) { return S_OK; } + STDMETHOD(CursorDown) (TABLET_CONTEXT_ID tcid, CURSOR_ID cid, ULONG nSerialNumber, ULONG cbPkt, BYTE * pbPkt) { return S_OK; } + STDMETHOD(CursorUp) (TABLET_CONTEXT_ID tcid, CURSOR_ID cid, ULONG nSerialNumber, ULONG cbPkt, BYTE * pbPkt) { return S_OK; } + STDMETHOD(Packets) (TABLET_CONTEXT_ID tcid, ULONG cPkts, ULONG cbPkts, BYTE * pbPkts, ULONG * pnSerialNumbers, CURSOR_ID cid) { return S_OK; } + STDMETHOD(SystemEvent) (TABLET_CONTEXT_ID tcid, CURSOR_ID cid, SYSTEM_EVENT, SYSTEM_EVENT_DATA) { return S_OK; } + }; + + CComPtr m_sink; + + + ///////////////////////////////////////////////////////////////////////// + + // data + + CComPtr m_pMgr; + CComPtr m_pCtxS; + TABLET_CONTEXT_ID m_tcid; + PACKET_DESCRIPTION * m_pPacketDescription; + + HANDLE m_hEventMoreData; + HANDLE m_hEventClientReady; + HANDLE m_hMutexSharedMemory; + HANDLE m_hFileMappingSharedMemory; + SHAREDMEMORY_HEADER * m_pSharedMemoryHeader; + BYTE * m_pbSharedMemoryRawData; + BYTE * m_pbSharedMemoryPackets; + BOOL m_fCommHandleOutstanding; + INT m_cHandles; + HANDLE * m_pHandles; + DWORD m_cbPackets; + BYTE* m_pbPackets; + SYSTEM_EVENT m_sysEvt; + SYSTEM_EVENT_DATA m_sysEvtData; + + HookThreadItemKey m_keyHookThreadItem; + CPimcManager::HookWindowItemKey m_keyHookWindowItem; + + HANDLE m_hEventUpdate; + DWORD m_dwUpdatesPending; + CRITICAL_SECTION m_csUpdates; + + BOOL m_fSingleFireTimeout : 1; + BOOL m_fIsTopmostHook : 1; + DWORD m_dwSingleFireTimeout; + + ComUtils::ComLockableWrapper m_contextLock; + ComUtils::ComLockableWrapper m_sinkLock; + ComUtils::GitComLockableWrapper m_wispContextLock; + + // DDVSO:514949 + // Special param flag for COM operations in GetPacketPropertyInfo. + static const int QUERY_WISP_CONTEXT_KEY = -1; +}; + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcManager.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcManager.cpp new file mode 100644 index 00000000000..0c8b10a8af4 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcManager.cpp @@ -0,0 +1,1188 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// PimcManager.cpp : Implementation of CPimcManager + +#include "stdafx.h" +#include "OSVersionHelper.h" +#include "PimcContext.h" +#include "PimcTablet.h" +#include "PimcManager.h" +#include "Penimc.h" +#include "shellapi.h" +#include +#include "osversionhelper.h" + +using namespace ComUtils; + +// from drivers/tablet/include/tabinc.h: +#define PENPROCESS_WISPTIS_REQUEST_EVENT _T("{773F1B9A-35B9-4E95-83A0-A210F2DE3B37}-request") +#define PENPROCESS_WISPTIS_RUNNING_EVENT _T("{773F1B9A-35B9-4E95-83A0-A210F2DE3B37}-running") +// Our local define for how long we'll wait for Tablet Input Service to load wisptis. +#define PENPROCESS_WISPTIS_LOADING_TIMEOUT 30000 // 30 seconds +#define WISPTIS_DIR _T("%SystemRoot%\\SYSTEM32\\") +#define WISPTIS_NAME _T("WISPTIS.EXE") +#define WISPTIS_MANUAL_LAUNCH _T("/ManualLaunch;") + +#define KERNEL32_NAME _T("KERNEL32") +#define WOW64DISABLEWOW64FSREDIRECTION_NAME "Wow64DisableWow64FsRedirection" +#define WOW64REVERTWOW64FSREDIRECTION_NAME "Wow64RevertWow64FsRedirection" +typedef BOOL (WINAPI *LPFNWOW64DISABLEWOW64FSREDIRECTION) (PVOID*); +typedef BOOL (WINAPI *LPFNWOW64REVERTWOW64FSREDIRECTION) (PVOID); + + +///////////////////////////////////////////////////////////////////////////// + +class CAsyncData +{ +public: + CAsyncData(DWORD dwArg, BOOL fArg = FALSE, BOOL fEventAck = FALSE) + : m_dwArg(dwArg), m_fArg(fArg) + { + m_hEventAck = fEventAck ? CreateEvent(NULL, FALSE, FALSE, NULL) : NULL; + } + ~CAsyncData() + { + if (m_hEventAck) + { + CloseHandle(m_hEventAck); + } + } + void SignalAck() + { + if (m_hEventAck) + SetEvent(m_hEventAck); + } + void WaitAck() + { + if (m_hEventAck) + { + WaitForSingleObject(m_hEventAck, INFINITE); + } + } + + HANDLE m_hEventAck; + DWORD_PTR m_dwArg; + BOOL m_fArg; + DWORD_PTR m_dwRes; +}; + +///////////////////////////////////////////////////////////////////////////// +// CPimcManager + +///////////////////////////////////////////////////////////////////////////// + +// Store the thread map globally so we can look up the manager given +// a window in the HookProc since we don't have access to an instance of the +// CPimcManager at that time. +CPbList g_HookThreadMap; + +HANDLE g_hMutexHook = NULL; + +#ifdef DBG_LATER +DWORD g_dwMutexHookOwnerThreadId = 0; +BOOL g_cHookLock = 0; +#endif + +CPimcManager::CPimcManager() : +#if WANT_PROFILE + m_fIsProfilingCached(FALSE), +#endif + m_fLoadedWisptis(FALSE) +{ +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcManager::FinalConstruct() +{ + DHR; + + // DDVSO:514949 + // Calling this ensures that the CStdIdentity for this IPimcManager3 is + // not released if we hit a COM rundown due to OSGVSO:10779198. + m_managerLock = ComLockableWrapper(this, ComApartmentVerifier::CurrentSta()); + CHR(m_managerLock.Lock()); + + // Verify the mutex we created in DllLoad went OK. + CHR(g_hMutexHook ? S_OK : E_FAIL); + +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +void CPimcManager::LoadWisptis() +{ + DHR; + + if (!m_fLoadedWisptis) + { + // ********** + // NOTE: PenIMC has duplicated the code for loading wisptis from InkObj. + // Whenever WIC team makes any changes, we should coordinate with them to work on fixes. + // ********** + if (IsVistaOrGreater()) + { + // DDVSO 144719. There are some scenarios were we must skip loading wisptis since + // they are not supported and can cause delays or crashes. + if (ShouldLoadWisptis()) + { + // we do this to signal TabSvc that it needs to spin up wisptis + // so that it is at the right IL. + HANDLE hEventRequest = OpenEvent(EVENT_MODIFY_STATE, FALSE, PENPROCESS_WISPTIS_REQUEST_EVENT); + HANDLE hEventRunning = OpenEvent(SYNCHRONIZE, FALSE, PENPROCESS_WISPTIS_RUNNING_EVENT); + + //if we don't have the event (TabSvc isn't running), or we timed out, + // that means Wisptis isn't running, so we'll start it; we do this via + // ShellExecute so that it gets started at high-IL (as indicated by + // Wisptis's manifest) to avoid IL-mismatch issues + //we allow wisptis to be started without TabSvc for backcompat + + if(hEventRunning == NULL) + { + // create the event since TabSvc isn't running + hEventRunning = CreateEvent(NULL, TRUE, FALSE, PENPROCESS_WISPTIS_RUNNING_EVENT); + } + + if(hEventRequest != NULL && hEventRunning != NULL) + { + //when this wait returns, wisptis will have registered its classes with COM + //if this fails or times out, we'll risk starting wisptis at a mismatched IL + DWORD dwResult = SignalObjectAndWait(hEventRequest, hEventRunning, 30000 /* thirty seconds */, FALSE); + + hr = dwResult == WAIT_OBJECT_0 ? S_OK : E_FAIL; + } + + // DDVSO:398137 + // Since hEventRequest is no longer of use at this point, close the handle. + SafeCloseHandle(&hEventRequest); + + if(/* wait timed out */ FAILED(hr) || + /* couldn't open the event for some reason */ hEventRunning == NULL || + /* wisptis isn't already running */ WaitForSingleObject(hEventRunning, 0) == WAIT_TIMEOUT) + { + PVOID pvOldValue = NULL; + BOOL bIsWow64 = FALSE; + LPFNWOW64DISABLEWOW64FSREDIRECTION fnWow64DisableWow64FsRedirection = NULL; + LPFNWOW64REVERTWOW64FSREDIRECTION fnWow64RevertWow64FsRedirection = NULL; + HMODULE hKernel32 = NULL; + + // Check whether this is running under Wow64 and, if so, disable file system redirection + // on the current thread - otherwise it will look for wisptis in the syswow64 directory + // instead of system32. + TPDBG_VERIFY(IsWow64Process(GetCurrentProcess(),&bIsWow64)); + if (bIsWow64) + { + // NOTICE-2006/06/13-WAYNEZEN, + // Since penimc may also run on the top of XPSP2, We cannot call Wow64DisableWow64FsRedirection/Wow64RevertWow64FsRedirection + // directly. Otherwise it will cause Entry Point Not Found error even though we don't really on those functions on 32-bit XP. + // So we have to use GetProcAddress to resovle the function address dynamically. + hKernel32 = GetModuleHandle(KERNEL32_NAME); + fnWow64DisableWow64FsRedirection = (LPFNWOW64DISABLEWOW64FSREDIRECTION)GetProcAddress( + hKernel32, WOW64DISABLEWOW64FSREDIRECTION_NAME); + fnWow64RevertWow64FsRedirection = (LPFNWOW64REVERTWOW64FSREDIRECTION)GetProcAddress( + hKernel32, WOW64REVERTWOW64FSREDIRECTION_NAME); + + TPDBG_VERIFY(fnWow64DisableWow64FsRedirection(&pvOldValue)); + } + + SHELLEXECUTEINFO sei = {0}; + + sei.cbSize = sizeof(sei); + sei.lpFile = WISPTIS_DIR WISPTIS_NAME; + sei.lpParameters = WISPTIS_MANUAL_LAUNCH; + sei.lpVerb = NULL; + sei.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI; + sei.lpDirectory = WISPTIS_DIR; + sei.hInstApp = (HINSTANCE)0; + + BOOL bResult = ShellExecuteEx(&sei); + + // Restore the file system redirection settings. + if (bIsWow64) + { + TPDBG_VERIFY(fnWow64RevertWow64FsRedirection(pvOldValue)); + } + + hr = bResult ? S_OK : E_FAIL; + if(FAILED(hr)) + { + OutputDebugString(L"PimcManager::LoadWisptis failed to ShellExecuteEx.\r\n"); + } + } + + if(SUCCEEDED(hr) && hEventRunning != NULL) + { + (void)WaitForSingleObject(hEventRunning, PENPROCESS_WISPTIS_LOADING_TIMEOUT /* 30 seconds */); + //regardless of the return from this, we'll still try to spin wisptis up via COM + } + + SafeCloseHandle(&hEventRunning); + + if(SUCCEEDED(hr)) + { + CHR(m_pMgrS.CoCreateInstance(CLSID_TabletManagerS)); //, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER)); + + // Ensure the WISP tablet manager is added to the GIT. + m_wispManagerLock = GitComLockableWrapper(m_pMgrS, ComApartmentVerifier::Mta()); + CHR(m_wispManagerLock.CheckCookie()); + + m_fLoadedWisptis = TRUE; + } + } + } + else + { + // To get around the issue with spinning up two wisptis.exe instances per user session we create an + // object that is a local server (using DllHost.exe to host one of our objects out of proc) that is + // marked as RunAs="Interactive User" to make sure it gets launched with the user's full priveledges. + // We then CoCreateInstance the wisptis.exe object from there to ensure we don't spin up an extra instance + // of wisptis.exe. The PimcSurrogate object is implemented in penimc.dll. + CComPtr pSurrogate; + CComPtr pTabletManager; + CHR(pSurrogate.CoCreateInstance(CLSID_PimcSurrogate3, NULL, CLSCTX_LOCAL_SERVER)); + CHR(pSurrogate != NULL ? S_OK : E_UNEXPECTED); + CHR(pSurrogate->GetWisptisITabletManager(&pTabletManager)); + CHR(pTabletManager->QueryInterface(IID_ITabletManager, (void**)&m_pMgrS)); + m_fLoadedWisptis = TRUE; + } + } + +CLEANUP: + // No return code needed. + return; +} + +///////////////////////////////////////////////////////////////////////////// + +BOOL CPimcManager::IsVistaOrGreater() +{ + static bool bIsVistaOrGreater = WPFUtils::OSVersionHelper::IsWindowsVistaOrGreater(); + return bIsVistaOrGreater; +} + +///////////////////////////////////////////////////////////////////////////// + +BOOL CPimcManager::ShouldLoadWisptis() +{ + // DDVSO 144719. Wisptis(Vista & 7) doesn't support inking while running under the system account + // Wisp (Win8 and above) supports this scenario, so we check for OS version and then for system account + static bool bShouldLoadWisptis = WPFUtils::OSVersionHelper::IsWindows8OrGreater() || + !UserIsLocalSystem(); + return bShouldLoadWisptis; +} + +///////////////////////////////////////////////////////////////////////////// + +BOOL CPimcManager::UserIsLocalSystem() +{ + BOOL fLocalSystem = FALSE; + + HANDLE hProcess = GetCurrentProcess(); + HANDLE hToken; + if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) + { + DWORD retLength = 0; + GetTokenInformation(hToken, TokenUser, nullptr, 0, &retLength); + if (retLength) + { + BYTE* tUser = new (std::nothrow) BYTE[retLength]; + if (tUser) + { + DWORD dwRealLength = retLength; + if(GetTokenInformation(hToken, TokenUser, tUser, dwRealLength, &retLength)) + { + PSID SIDSystem; + SID_IDENTIFIER_AUTHORITY siaNT = SECURITY_NT_AUTHORITY; + if(AllocateAndInitializeSid(&siaNT, 1, SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, &SIDSystem)) + { + fLocalSystem = EqualSid(((TOKEN_USER*)tUser)->User.Sid, SIDSystem); + FreeSid(SIDSystem); + } + } + delete [] tUser; + } + } + CloseHandle(hToken); + } + + return fLocalSystem; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcManager::InitializeHookThread(__inout CHookThreadItem * pThread) +{ + DHR; + + BOOL fCleanupThread = FALSE; + CAsyncData * pAsyncData = NULL; + + DWORD dwHookThread = 0; + DWORD dwWaitHookThread = WAIT_FAILED; + + // Only need to do this once. + ASSERT(!pThread->m_hHook); + + // hook handling + pThread->m_hEventHookThreadReady = CreateEvent(NULL, FALSE, FALSE, NULL); + pThread->m_hEventHookThreadExit = CreateEvent(NULL, FALSE, FALSE, NULL); + pThread->m_hEventHookThreadExitAck = CreateEvent(NULL, FALSE, FALSE, NULL); + // timer to deal with hosting in other processes (don't get move event) + pThread->m_hTimer = CreateWaitableTimer(NULL, TRUE, NULL); // last param make this Waitable Timer + + CHR((pThread->m_hEventHookThreadReady != NULL && pThread->m_hEventHookThreadExit != NULL && + pThread->m_hEventHookThreadExitAck != NULL && pThread->m_hTimer != NULL) ? S_OK : E_FAIL); + + pThread->m_hHookThread = CreateThread(NULL, 0, HookThreadProc, (LPVOID)pThread, 0, &dwHookThread); + CHR(pThread->m_hHookThread ? S_OK : E_FAIL); + + dwWaitHookThread = WaitForSingleObject(pThread->m_hEventHookThreadReady, INFINITE); + CHR(dwWaitHookThread == WAIT_OBJECT_0 ? S_OK : E_FAIL); + fCleanupThread = true; + + // post the APC call + CHR_MEMALLOC(pAsyncData = new CAsyncData(/*dwArg*/pThread->m_dwThreadId, /*fArg*/FALSE, /*fEventDone*/TRUE)); + CHR(QueueUserAPC(InstallWindowHookApcCore, pThread->m_hHookThread, (ULONG_PTR)pAsyncData) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_QUEUEUSERAPC_CALL)); + pAsyncData->WaitAck(); + pThread->m_hHook = (HHOOK)pAsyncData->m_dwRes; + delete pAsyncData; + pAsyncData = NULL; + + RHR; + +CLEANUP: + if (fCleanupThread) + { + SignalObjectAndWait(pThread->m_hEventHookThreadExit, pThread->m_hEventHookThreadExitAck, INFINITE, FALSE); + } + if (pAsyncData) + { + delete pAsyncData; + } + SafeCloseHandle(&pThread->m_hHookThread); + SafeCloseHandle(&pThread->m_hEventHookThreadReady); + SafeCloseHandle(&pThread->m_hEventHookThreadExit); + SafeCloseHandle(&pThread->m_hEventHookThreadExitAck); + SafeCloseHandle(&pThread->m_hTimer); + + RHR; +} + +void CPimcManager::TerminateHookThread(__inout CHookThreadItem * pThread) +{ + // Only do this once. + if (pThread->m_hHook != NULL) + { + UnhookWindowsHookEx(pThread->m_hHook); + SignalObjectAndWait(pThread->m_hEventHookThreadExit, pThread->m_hEventHookThreadExitAck, INFINITE, FALSE); + pThread->m_hHook = NULL; + SafeCloseHandle(&pThread->m_hHookThread); + SafeCloseHandle(&pThread->m_hEventHookThreadReady); + SafeCloseHandle(&pThread->m_hEventHookThreadExit); + SafeCloseHandle(&pThread->m_hEventHookThreadExitAck); + SafeCloseHandle(&pThread->m_hTimer); + } +} + + +///////////////////////////////////////////////////////////////////////////// + +void CPimcManager::FinalRelease() +{ + m_wispManagerLock.RevokeIfValid(); +} + +///////////////////////////////////////////////////////////////////////////// +// +// CPimcManager::HookThreadProc +// +// This thread is used to install hooks for contexts. The thread is alertable for APCs and +// the actual installation of the hook happens in InstallWindowHookApcCore. +// +// IMPORTANT NOTE (alexz): there was a significant amount of investigation done about +// what is the correct logic to maintain hook on a window when done in COM in-proc servers. +// See Tablet V1 Raid bugs # 17589, 23860 for details. +// In particular, note that we can not install the hooks from the thread that invokes +// CPimcContext. This is because the thread used is from the thread pool (either CLR or COM RPC), +// and can be switched at any moment. When the switch happens, Windows disconnects the hook. +// + +DWORD CPimcManager::HookThreadProc(__typefix(CHookThreadItem *) __in LPVOID pvParam) +{ + DHR; + CHookThreadItem * pThread = (CHookThreadItem*)pvParam; + ASSERT (pThread); + + CHR(SetEvent(pThread->m_hEventHookThreadReady) ? S_OK : E_FAIL); + + // MAIN LOOP + { + BOOL fLoop = TRUE; + HANDLE waitHandles[2] = { pThread->m_hEventHookThreadExit, pThread->m_hTimer }; + while (fLoop) + { + DWORD dwWait = MsgWaitForMultipleObjectsEx( + 2, &(waitHandles[0]), INFINITE, + QS_ALLEVENTS, MWMO_ALERTABLE); + + switch (dwWait) + { + case WAIT_OBJECT_0 + 0: // m_hEventHookThreadExit + fLoop = FALSE; + break; + + case WAIT_OBJECT_0 + 1: // waitable timer triggered + // See if any of our contexts have changed location + HandleTimer(pThread->m_dwThreadId); + fLoop = TRUE; + break; + + case WAIT_OBJECT_0 + 2: // a message in the queue of this thread + { + MSG msg; + PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE); // this will cause hook proc to get invoked + } + fLoop = TRUE; + break; + + case WAIT_IO_COMPLETION: // (an APC call will trigger this) + fLoop = TRUE; + break; + + default: + ASSERT(FALSE && "CPimcManager::HookThreadProc: an unexpected error in the wait"); + fLoop = FALSE; + break; + } + } + } + +CLEANUP: + SetEvent(pThread->m_hEventHookThreadExitAck); + + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// + +// A new PimcContext is created, make sure we have a hook set up. +HRESULT CPimcManager::InstallWindowHook(__in HWND hwnd, __inout CPimcContext * pCtx) +{ + DHR; + DWORD dwProcessId; + CAsyncData * pAsyncData = NULL; + BOOL fCleanupThreadItem = false; + BOOL fCleanupHook = false; + BOOL fCleanupWindowItem = false; + BOOL fAddedMgr = FALSE; + + HookThreadItemKey keyHookThreadItem = NULL; + CHookThreadItem * pHookThreadItem = NULL; + HookWindowItemKey keyHookWindowItem = NULL; + CHookWindowItem * pHookWindowItem = NULL; + + ASSERT (hwnd && IsWindow(hwnd)); + + // DDVSO:220285 + // Scope the CHookLock so we don't attempt to call TerminateWindowHook + // under the lock (see UninstallWindowHook). + { + CHookLock lock; + + // we don't allow handling of hwnd-s not owned by this process + DWORD dwThreadId = GetWindowThreadProcessId(hwnd, &dwProcessId); + DWORD dwProcessIdCur = GetCurrentProcessId(); + CHR(dwProcessIdCur == dwProcessId ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_GETCURRENTPROCESSID_CALL)); //..WIP (alexz) use TPC_E_INVALID_WINDOW_HANDLE + + // register in m_HookThreadMap + + CHR(EnsureHookThreadItem(dwThreadId, this, &keyHookThreadItem, &fAddedMgr)); + pHookThreadItem = &(g_HookThreadMap[keyHookThreadItem]); + pHookThreadItem->m_cUsages++; + fCleanupThreadItem = true; + + // Set up the window hook if it has not been done yet for this thread. + if (!pHookThreadItem->m_hHook) + { + CHR(InitializeHookThread(pHookThreadItem)); + fCleanupHook = true; + } + + pCtx->m_keyHookThreadItem = keyHookThreadItem; + + // register in m_HookWindowMap + + CHR(EnsureHookWindowItem(hwnd, &keyHookWindowItem)); + fCleanupWindowItem = true; + pHookWindowItem = &(m_HookWindowMap[keyHookWindowItem]); + CHR(pHookWindowItem->m_ctxs.Add(pCtx)); + + pCtx->m_keyHookWindowItem = keyHookWindowItem; + + // Now see if we need to start the waittimer + if (pHookWindowItem->m_bNeedsTimer && !pHookThreadItem->m_bTimerStarted) + { + StartWaitTimer(pHookThreadItem); + } + + RHR; + + CLEANUP: + + if (pAsyncData) + delete pAsyncData; + + if (fCleanupThreadItem) + { + if (fAddedMgr) + { + for (INT i = 0; pHookThreadItem->m_mgrs.GetSize(); i++) + { + if (pHookThreadItem->m_mgrs[i] == this) + { + pHookThreadItem->m_mgrs.Remove(i); + break; + } + } + } + + pHookThreadItem->m_cUsages--; + if (!pHookThreadItem->m_cUsages) + { + // DDVSO:424827 + // Keep pHookThreadItem alive until we terminate the hook thread + g_HookThreadMap.Remove(keyHookThreadItem, false /*deleteEntry*/); + } + } + + if (fCleanupWindowItem) + { + // Add of context failed so see if we need to unregister hwnd key in HookWindowMap + if (!pHookWindowItem->m_ctxs.GetSize()) + { + m_HookWindowMap.Remove(keyHookWindowItem, true /*deleteEntry*/); + } + } + } // End of CHookLock block + + if (fCleanupHook) + { + TerminateHookThread(pHookThreadItem); + delete pHookThreadItem; + } + + RHR; +} + + +/////////////////////////////////////////////////////////////////////////////// + +HookThreadItemKey CPimcManager::FindHookThreadItem(DWORD dwThreadId) +{ + HookThreadItemKey keyFound = NULL; + HookThreadItemKey keyCur = g_HookThreadMap.GetHead(); + while (!g_HookThreadMap.IsAtEnd(keyCur)) + { + if (g_HookThreadMap[keyCur].m_dwThreadId == dwThreadId) + { + keyFound = keyCur; + break; + } + keyCur = g_HookThreadMap.GetNext(keyCur); + } + return keyFound; +} + +/////////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcManager::EnsureHookThreadItem(DWORD dwThreadId, __in CPimcManager * pMgr, + __out HookThreadItemKey * pKey, __out BOOL *pfAddedManager) +{ + DHR; + *pfAddedManager = FALSE; + *pKey = FindHookThreadItem(dwThreadId); + if (!(*pKey)) + { + CHR(g_HookThreadMap.AddToTail(pKey)); + g_HookThreadMap[*pKey].m_dwThreadId = dwThreadId; + g_HookThreadMap[*pKey].m_cUsages = 0; + g_HookThreadMap[*pKey].m_hHook = NULL; + g_HookThreadMap[*pKey].m_hHookThread = NULL; + g_HookThreadMap[*pKey].m_hEventHookThreadReady = NULL; + g_HookThreadMap[*pKey].m_hEventHookThreadExit = NULL; + g_HookThreadMap[*pKey].m_hEventHookThreadExitAck = NULL; + g_HookThreadMap[*pKey].m_hTimer = NULL; + g_HookThreadMap[*pKey].m_bTimerStarted = false; + g_HookThreadMap[*pKey].m_mgrs.Add(pMgr); + } + else + { + // Make sure this manager has been added to the HookThreadItem mgr list + CHookThreadItem * pItem = &g_HookThreadMap[*pKey]; + + BOOL fFound = FALSE; + INT cMgrs = pItem->m_mgrs.GetSize(); + for (INT iMgr = 0; iMgr < cMgrs; iMgr++) + { + CPimcManager* pcurMgr = pItem->m_mgrs[iMgr]; + if (pcurMgr == pMgr) + { + fFound = TRUE; + break; + } + } + if (!fFound) + { + pItem->m_mgrs.Add(pMgr); + *pfAddedManager = TRUE; + } + } + +CLEANUP: + RHR; +} + +/////////////////////////////////////////////////////////////////////////////// + +CPimcManager::HookWindowItemKey CPimcManager::FindHookWindowItem(__in HWND hwnd) +{ + HookWindowItemKey keyFound = NULL; + HookWindowItemKey keyCur = m_HookWindowMap.GetHead(); + while (!m_HookWindowMap.IsAtEnd(keyCur)) + { + if (m_HookWindowMap[keyCur].m_hwnd == hwnd) + { + keyFound = keyCur; + break; + } + keyCur = m_HookWindowMap.GetNext(keyCur); + } + return keyFound; +} + +/////////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcManager::EnsureHookWindowItem(__in HWND hwnd, __out HookWindowItemKey * pKey) +{ + DHR; + *pKey = FindHookWindowItem(hwnd); + if (!(*pKey)) + { + CHR(m_HookWindowMap.AddToTail(pKey)); + m_HookWindowMap[*pKey].m_hwnd = hwnd; + m_HookWindowMap[*pKey].m_bNeedsTimer = false; + + // See if this hwnd needs tracking by the waitable timer + DWORD dwProcessId = 0; + DWORD dwThreadId = GetWindowThreadProcessId(hwnd, &dwProcessId); + HWND hwndParent = GetParent(hwnd); + while (hwndParent != NULL) + { + DWORD dwProcessIdParent = 0; + DWORD dwThreadIdParent = GetWindowThreadProcessId(hwndParent, &dwProcessIdParent); + if (dwProcessIdParent != dwProcessId || dwThreadIdParent != dwThreadId) + { + RECT rc = {0}; // Init to empty rect to make sure it triggers first time. + m_HookWindowMap[*pKey].m_rc = rc; + m_HookWindowMap[*pKey].m_bNeedsTimer = true; + break; + } + hwndParent = GetParent(hwndParent); + } + } + +CLEANUP: + RHR; +} + +/////////////////////////////////////////////////////////////////////////////// + +void CPimcManager::InstallWindowHookApcCore(__typefix(CAsyncData *) __inout ULONG_PTR pvAsyncData) +{ + CAsyncData * pAsyncData = (CAsyncData*)pvAsyncData; + DWORD dwThreadId = (DWORD)pAsyncData->m_dwArg; + + HHOOK hHook = SetWindowsHookEx(WH_CALLWNDPROC, HookProc, NULL, dwThreadId); + + pAsyncData->m_dwRes = (DWORD_PTR)hHook; + + pAsyncData->SignalAck(); +} + +/////////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcManager::UninstallWindowHook(__in CPimcContext * pCtx) +{ + DHR; + + CHookThreadItem * pThreadItem = NULL; + HookThreadItemKey keyHookThreadItem = NULL; + bool shouldTerminateHookThread = false; + + // DDVSO:220285 + // Keeping the CHookLock while the hook thread is being terminated in TerminateHookThread + // can lead to a deadlock situation. If any message comes through the hook thread + // or if the timer ticks while we have this lock, the hook thread itself may attempt + // to acquire the lock in several of its handlers. If this occurs, TerminateHookThread + // will eventually wait forever on m_hEventHookThreadExitAck which can never be signaled + // since the hook thread is waiting on CHookLock. + // + // To stop this occurring, scope the hook lock to only what needs a lock, the + // processing of contexts using the hook thread. Once contexts are manipulated + // we can signal the hook thread to exit with confidence that m_hEventHookThreadExitAck + // will be signaled as the hook thread is free to process. + { + CHookLock lock; + + // unregister in HookThreadMap + + keyHookThreadItem = pCtx->m_keyHookThreadItem; + pThreadItem = &g_HookThreadMap[keyHookThreadItem]; + + // unregister in HookWindowMap + + HookWindowItemKey keyHookWindowItem = pCtx->m_keyHookWindowItem; + CHookWindowItem * pWindowItem = &m_HookWindowMap[keyHookWindowItem]; + for (INT idx = 0; pWindowItem->m_ctxs.GetSize(); idx++) + { + if (pWindowItem->m_ctxs[idx] == pCtx) + { + pWindowItem->m_ctxs.Remove(idx); + break; + } + } + + BOOL bNeedsTimer = pWindowItem->m_bNeedsTimer; + if (pWindowItem->m_ctxs.GetSize() == 0) + { + m_HookWindowMap.Remove(keyHookWindowItem, true /*deleteEntry*/); + + // If no more windows on this manager, then remove this pMgr from the list + if (m_HookWindowMap.IsEmpty()) + { + for (INT i = 0; pThreadItem->m_mgrs.GetSize(); i++) + { + if (pThreadItem->m_mgrs[i] == this) + { + pThreadItem->m_mgrs.Remove(i); + break; + } + } + } + } + + // see if we can turn off waitabletimer + // Now see if we need to start the waittimer + if (bNeedsTimer && pThreadItem->m_bTimerStarted) + { + StopWaitTimerIfNotNeeded(pThreadItem); + } + + pThreadItem->m_cUsages--; + + if (pThreadItem->m_cUsages == 0) + { + // DDVSO:424827 + // Keep pThreadItem alive until we terminate the hook thread + g_HookThreadMap.Remove(keyHookThreadItem, false /*deleteEntry*/); + shouldTerminateHookThread = true; + } + } // End of CHookLock block + + if (shouldTerminateHookThread) + { + TerminateHookThread(pThreadItem); + delete pThreadItem; + } + + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +LRESULT CALLBACK CPimcManager::HookProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + PCWPSTRUCT pcwp = (PCWPSTRUCT)lParam; + HWND hwnd = pcwp->hwnd; + DWORD dwTid; + DWORD dwPid; + + if (!IsWindow(hwnd)) + goto CLEANUP; + + dwTid = GetWindowThreadProcessId(hwnd, &dwPid); + if (dwTid == 0 || GetCurrentProcessId() != dwPid) + goto CLEANUP; + + try + { + //static BOOL fInSizeMove = FALSE; + + if (0 <= nCode) + { + switch (pcwp->message) + { + case WM_MDIACTIVATE: + MgrHandleCtxUpdate(dwTid, CPimcContext::UPDATE_SendToTop, (HWND)pcwp->lParam); + break; + + case WM_ACTIVATE: + { + if (WA_INACTIVE != pcwp->wParam) + { + MgrHandleCtxUpdate(dwTid, CPimcContext::UPDATE_SendToTop, hwnd); + } + } + break; + + case WM_CHILDACTIVATE: + MgrHandleCtxUpdate(dwTid, CPimcContext::UPDATE_SendToTop, hwnd); + break; + + //case WM_INITMENUPOPUP: + // MgrHandleCtxUpdate(dwTid, CPimcContext::UPDATE_SendToBack, hwnd); + // break; + + case WM_UNINITMENUPOPUP: + MgrHandleCtxUpdate(dwTid, CPimcContext::UPDATE_SendToTop, hwnd); + break; + + case WM_COMMAND: + if ((HIWORD(pcwp->wParam) == CBN_CLOSEUP)) + { + MgrHandleCtxUpdate(dwTid, CPimcContext::UPDATE_SendToTop, hwnd); + } + break; + + case WM_SIZE: + case WM_MOVE: + MgrHandleCtxUpdate(dwTid, CPimcContext::UPDATE_SizeMove, hwnd); + break; + +#if 0 //..WIP (alexz) + case WM_ENTERSIZEMOVE: + MgrHandleCtxUpdate(dwTid, CPimcContext::UPDATE_Disable, hwnd); + fInSizeMove = TRUE; + break; + + case WM_SETCURSOR: + if (!fInSizeMove) + break; + // else + // fall thru + + case WM_EXITSIZEMOVE: + //..WIP (alexz) this is not correct if the context was disabled + MgrHandleCtxUpdate(dwTid, CPimcContext::UPDATE_Enable, hwnd); + fInSizeMove = FALSE; + break; + + case WM_DESTROY: + MgrHandleCtxUpdate(dwTid, CPimcContext::UPDATE_Unhook, hwnd); + break; +#endif + } + } + } + catch (...) + { + ASSERT(FALSE && "not reached"); + } + +CLEANUP: + + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + + +///////////////////////////////////////////////////////////////////////////// + +void CPimcManager::HandleTimer(DWORD dwThreadId) +{ + CHookLock lock; + + // Look up CHookThreadItem instance for this thread. + HookThreadItemKey hookThreadKey = FindHookThreadItem(dwThreadId); + CHookThreadItem * pThreadItem = &g_HookThreadMap[hookThreadKey]; + + // DDVSO:220285 + // If the CHookThreadItem is either awaiting cleanup due to a failed install + // or we are uninstalling the hook thread, do not initiate processing. Both + // cleanup and uninstall will remove the last entry for a CHookThreadItem, so + // if the result of the lookup is NULL we know we are in a cleanup/shutdown + // scenario. + if (NULL != pThreadItem) + { + // Loop through the CPimcManager list looking for contexts that need the timer. + INT cMgrs = pThreadItem->m_mgrs.GetSize(); + for (INT i = 0; i < cMgrs; i++) + { + CPimcManager* pMgr = pThreadItem->m_mgrs[i]; + + HookWindowItemKey keyCur = pMgr->m_HookWindowMap.GetHead(); + while (!pMgr->m_HookWindowMap.IsAtEnd(keyCur)) + { + CHookWindowItem * pItem = &pMgr->m_HookWindowMap[keyCur]; + if (pItem->m_bNeedsTimer) + { + HWND hwnd = pItem->m_hwnd; + // Only do this work if the window is still valid. + if (::IsWindow(hwnd)) + { + RECT rc = { 0 }; + ::GetWindowRect(hwnd, &rc); + if (!EqualRect(&rc, &(pItem->m_rc))) + { + pItem->m_rc = rc; + // We only need to update contexts for this window (any children will also use timer). + INT c = pItem->m_ctxs.GetSize(); + for (INT i = 0; i < c; i++) + { + CPimcContext * pCtx = pItem->m_ctxs[i]; + pCtx->PostUpdate(CPimcContext::UPDATE_SizeMove); + } + } + } + } + keyCur = pMgr->m_HookWindowMap.GetNext(keyCur); + } + } + + StartWaitTimer(pThreadItem); + } +} + +///////////////////////////////////////////////////////////////////////////// + +void CPimcManager::StartWaitTimer(__inout CHookThreadItem * pThread) +{ + LARGE_INTEGER liDueTime; + liDueTime.QuadPart=-WAITTIMER_DELAY; + + pThread->m_bTimerStarted = SetWaitableTimer(pThread->m_hTimer, &liDueTime, 0, NULL, NULL, 0); +} + +///////////////////////////////////////////////////////////////////////////// + +void CPimcManager::StopWaitTimerIfNotNeeded(__inout CHookThreadItem * pThread) +{ + // If no other contexts require timer then stop it. + if (!DoContextsNeedWaitableTimer(pThread)) + { + CancelWaitableTimer(pThread->m_hTimer); + pThread->m_bTimerStarted = FALSE; + } +} + +///////////////////////////////////////////////////////////////////////////// + +BOOL CPimcManager::DoContextsNeedWaitableTimer(__in CHookThreadItem * pThread) +{ + // Loop through the CPimcManager list looking for contexts that need the timer. + INT cMgrs = pThread->m_mgrs.GetSize(); + for (INT i = 0; i < cMgrs; i++) + { + CPimcManager* pMgr = pThread->m_mgrs[i]; + + HookWindowItemKey keyCur = pMgr->m_HookWindowMap.GetHead(); + while (!pMgr->m_HookWindowMap.IsAtEnd(keyCur)) + { + if (pMgr->m_HookWindowMap[keyCur].m_bNeedsTimer) + { + return TRUE; + } + keyCur = pMgr->m_HookWindowMap.GetNext(keyCur); + } + } + return FALSE; +} + + +///////////////////////////////////////////////////////////////////////////// + + +void CPimcManager::MgrHandleCtxUpdate(DWORD dwThreadId, DWORD dwUpdate, __in HWND hwnd) +{ + CHookLock lock; + + // Look up CPimcManager instance for this thread and process update on that instance. + HookThreadItemKey hookThreadKey = FindHookThreadItem(dwThreadId); + CHookThreadItem * pThreadItem = &g_HookThreadMap[hookThreadKey]; + + if (pThreadItem != NULL) + { + PostCtxUpdateForSubtree(dwUpdate, hwnd, pThreadItem); + } +} + +///////////////////////////////////////////////////////////////////////////// + +void CPimcManager::PostCtxUpdateForWnd(DWORD dwUpdate, __in HWND hwnd, __in CHookThreadItem * pThreadItem) +{ + // Since we can have multiple CPimcManager objects per thread we need to enum + // them and notify all of them of this context update for this hwnd. + INT cMgrs = pThreadItem->m_mgrs.GetSize(); + for (INT iMgr = 0; iMgr < cMgrs; iMgr++) + { + CPimcManager* pMgr = pThreadItem->m_mgrs[iMgr]; + + HookWindowItemKey key = pMgr->FindHookWindowItem(hwnd); + if (key) + { + CHookWindowItem * pItem = &(pMgr->m_HookWindowMap[key]); + + // Update our rect if the hookproc window messages triggers an update to our size. + if (pItem->m_bNeedsTimer && ((dwUpdate & CPimcContext::UPDATE_SizeMove) != 0)) + { + RECT rc = {0}; + ::GetWindowRect(pItem->m_hwnd, &rc); + pItem->m_rc = rc; + } + + INT c = pItem->m_ctxs.GetSize(); + for (INT i = 0; i < c; i++) + { + CPimcContext * pCtx = pItem->m_ctxs[i]; + pCtx->PostUpdate(dwUpdate); + } + } + } +} + +///////////////////////////////////////////////////////////////////////////// + +void CPimcManager::PostCtxUpdateForSubtree(DWORD dwUpdate, __in HWND hwndRoot, __in CHookThreadItem * pThreadItem) +{ + try + { + DHR; + CPbList queue; + CHR(queue.AddToTail(hwndRoot)); + for (;;) + { + PBLKEY keyHead = queue.GetHead(); + if (queue.IsAtEnd(keyHead)) + break; + + HWND hwndCur = queue[keyHead]; + queue.Remove(keyHead, true /*deleteEntry*/); + + // handle the event for this hwnd + PostCtxUpdateForWnd(dwUpdate, hwndCur, pThreadItem); + + // enumerate children + hwndCur = ::GetWindow(hwndCur, GW_CHILD); + if (hwndCur) + { + hwndCur = ::GetWindow(hwndCur, GW_HWNDLAST); + while (hwndCur) + { + CHR(queue.AddToTail(hwndCur)); + hwndCur= ::GetWindow(hwndCur, GW_HWNDPREV); + } + } + } +CLEANUP: + return; + } + catch (...) + { + } +} + +///////////////////////////////////////////////////////////////////////////// + +#if WANT_PROFILE +BOOL CPimcManager::IsProfiling() +{ + if (!m_fIsProfilingCached) + { + m_fIsProfilingCached = TRUE; + m_fIsProfiling = FALSE; + + HKEY hKey; + if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CURRENT_USER, SZ_REGKEY_PROFILE, 0, KEY_QUERY_VALUE, &hKey)) + { + DWORD cbSize = sizeof(DWORD); + DWORD dwProfiling = 0; + RegQueryValueExW(hKey, L"V2Profiling", NULL, NULL, (BYTE*) &dwProfiling, &cbSize); + RegCloseKey(hKey); + + m_fIsProfiling = dwProfiling != 0; + } + } + return m_fIsProfiling; +} +#endif + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcManager::GetTabletCount(__out ULONG* pcTablets) +{ + DHR; + + ULONG cTablets = 0; + + LoadWisptis(); // Try to load wisptis via the surrogate object. + + // we will return 0 in the case that there is no stylus since mouse is not considered a stylus anymore + if (m_fLoadedWisptis) + { + CHR(m_pMgrS->GetTabletCount(&cTablets)); + } + + *pcTablets = cTablets; + +CLEANUP: + RHR; +} + + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcManager::GetTablet(ULONG iTablet, __deref_out IPimcTablet3** ppTablet) +{ + DHR; + + switch (iTablet) + { + case RELEASE_MANAGER_EXT: + { + CHR(m_managerLock.Unlock()); + } + break; + default: + { + CHR(GetTabletImpl(iTablet, ppTablet)); + } + } + +CLEANUP: + RHR; +} + +STDMETHODIMP CPimcManager::GetTabletImpl(ULONG iTablet, __deref_out IPimcTablet3** ppTablet) +{ + DHR; + LoadWisptis(); // Make sure wisptis has been loaded! (Can happen when handling OnTabletAdded message) + + CComPtr pTabS; + CComObject * pTabC; + + // Can only call if we have real tablet hardware which means wisptis must be loaded! + CHR(m_fLoadedWisptis ? S_OK : E_UNEXPECTED); + CHR(CComObject::CreateInstance(&pTabC)); + CHR(pTabC->QueryInterface(IID_IPimcTablet3, (void**)ppTablet)); + CHR(m_pMgrS->GetTablet(iTablet, &pTabS)); + CHR(pTabC->Init(m_fLoadedWisptis?pTabS:NULL, this)); + +CLEANUP: + RHR; +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcManager.h b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcManager.h new file mode 100644 index 00000000000..18d48f63819 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcManager.h @@ -0,0 +1,197 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// PimcManager.h : Declaration of the CPimcManager + +#pragma once +#include "resource.h" // main symbols + +#include "PenImc.h" +#include "PbList.h" +#include "PbPreallocArray.h" +#include "ComLockableWrapper.hpp" +#include "GitComLockableWrapper.hpp" + +class CPimcContext; +class CPimcManager; + + +// thread map +struct CHookThreadItem +{ + DWORD m_dwThreadId; + HHOOK m_hHook; + DWORD m_cUsages; + CPbPreallocArray m_mgrs; + + // Used to manage the hook thread + HANDLE m_hHookThread; + HANDLE m_hEventHookThreadReady; + HANDLE m_hEventHookThreadExit; + HANDLE m_hEventHookThreadExitAck; + HANDLE m_hTimer; + BOOL m_bTimerStarted : 1; +}; +typedef PBLKEY HookThreadItemKey; + +extern HANDLE g_hMutexHook; + +#ifdef DBG_LATER +extern DWORD g_dwMutexHookOwnerThreadId; +extern BOOL g_cHookLock; +#endif + +#define WAITTIMER_DELAY 2500000 // 250 milliseconds (1/4 sec) + +///////////////////////////////////////////////////////////////////////////// +// CPimcManager + +class ATL_NO_VTABLE CPimcManager : + public CComObjectRootEx, + public CComCoClass, + public IPimcManager3 +{ +public: + + ///////////////////////////////////////////////////////////////////////// + + CPimcManager(); + + HRESULT FinalConstruct(); + void FinalRelease(); + void LoadWisptis(); + BOOL IsVistaOrGreater(); + +protected: + + BOOL ShouldLoadWisptis(); + BOOL UserIsLocalSystem(); + +public: + +#if WANT_PROFILE + BOOL IsProfiling(); +#endif + + HRESULT RegisterCtxS(__in ITabletContextP * pCtxS, __out DWORD * pdwCookie); + HRESULT RevokeCtxS (DWORD dwCookie); + HRESULT GetCtxS (DWORD dwCookie, __deref_out ITabletContextP ** ppCtxS); + + // + // hook handling + // + + // methods + + HRESULT InstallWindowHook(__in HWND hwnd, __inout CPimcContext * pCtx); + HRESULT UninstallWindowHook(__in CPimcContext * pCtx); + static DWORD WINAPI HookThreadProc(__typefix(CHookThreadItem *) __in LPVOID pvParam); + static void CALLBACK InstallWindowHookApcCore(__typefix(CAsyncData *) __inout ULONG_PTR pvAsyncData); + static HRESULT InitializeHookThread(__inout CHookThreadItem * pThread); + static void TerminateHookThread(__inout CHookThreadItem * pThread); + + typedef PBLKEY HookWindowItemKey; + + struct CHookWindowItem + { + HWND m_hwnd; + BOOL m_bNeedsTimer; + RECT m_rc; + CPbPreallocArray m_ctxs; + }; + + // tracks windows for this manager thread + CPbList m_HookWindowMap; + + static HookThreadItemKey FindHookThreadItem(DWORD dwThreadId); + HRESULT EnsureHookThreadItem(DWORD dwThreadId, __in CPimcManager * pMgr, __out HookThreadItemKey * pKey, __out BOOL *pfAddedManager); + HookWindowItemKey FindHookWindowItem(__in HWND hwnd); + HRESULT EnsureHookWindowItem(__in HWND hwnd, __out HookWindowItemKey * pKey); + + static LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam); + + static void HandleTimer(DWORD dwThreadId); + static void StartWaitTimer(__inout CHookThreadItem * pThread); + static void StopWaitTimerIfNotNeeded(__inout CHookThreadItem * pThread); + static BOOL DoContextsNeedWaitableTimer(__in CHookThreadItem * pThread); + static void MgrHandleCtxUpdate(DWORD dwThreadId, DWORD dwUpdate, __in HWND hwnd); + static void PostCtxUpdateForSubtree(DWORD dwUpdate, __in HWND hwndRoot, __in CHookThreadItem * pThreadItem); + static void PostCtxUpdateForWnd(DWORD dwUpdate, __in HWND hwnd, __in CHookThreadItem * pThreadItem); + + // locking + + class CHookLock + { + public: + CHookLock() + { + m_dwWait = 0; + ASSERT(g_hMutexHook); + if (g_hMutexHook) + { + m_dwWait = WaitForSingleObject(g_hMutexHook, INFINITE); + ASSERT (m_dwWait == WAIT_OBJECT_0); + } +#ifdef DBG_LATER + g_cHookLock++; + g_dwMutexHookOwnerThreadId = GetCurrentThreadId(); +#endif + } + ~CHookLock() + { +#ifdef DBG_LATER + g_dwMutexHookOwnerThreadId = 0; + g_cHookLock--; +#endif + if (m_dwWait == WAIT_OBJECT_0) + ReleaseMutex(g_hMutexHook); + } + + protected: + DWORD m_dwWait; + }; + + // + // IPimcManager3 + // + + STDMETHOD(GetTabletCount)(__out ULONG* pcTablets); + STDMETHOD(GetTablet)(ULONG iTablet, __deref_out IPimcTablet3** ppTablet); + STDMETHOD(GetTabletImpl)(ULONG iTablet, __deref_out IPimcTablet3** ppTablet); + + // wiring + +DECLARE_REGISTRY_RESOURCEID(IDR_PIMCMANAGER) + +BEGIN_COM_MAP(CPimcManager) + COM_INTERFACE_ENTRY(IPimcManager3) +END_COM_MAP() + + DECLARE_PROTECT_FINAL_CONSTRUCT() + + ///////////////////////////////////////////////////////////////////////// + + // data + CComPtr m_pMgrS; + ComUtils::GitComLockableWrapper m_wispManagerLock; + + BOOL m_fLoadedWisptis : 1; + + ComUtils::ComLockableWrapper m_managerLock; + + // DDVSO:514949 + // Special param flag for COM operations in GetTablet + const static ULONG RELEASE_MANAGER_EXT = 0xFFFFDEAD; + +#if WANT_PROFILE + BOOL m_fIsProfilingCached : 1; + BOOL m_fIsProfiling : 1; +#endif // WANT_PROFILE +}; + +///////////////////////////////////////////////////////////////////////////// + +OBJECT_ENTRY_AUTO(__uuidof(PimcManager3), CPimcManager) + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcSurrogate.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcSurrogate.cpp new file mode 100644 index 00000000000..113a4243827 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcSurrogate.cpp @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// PimcSurrogate.cpp : Implementation of CPimcSurrogate + +#include "stdafx.h" +#include "Penimc.h" +#include "PimcSurrogate.h" +#include +#include + +///////////////////////////////////////////////////////////////////////////// +// CPimcSurrogate + +///////////////////////////////////////////////////////////////////////////// + +CPimcSurrogate::CPimcSurrogate() +{ +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcSurrogate::FinalConstruct() +{ + DHR; + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +void CPimcSurrogate::FinalRelease() +{ +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcSurrogate::GetWisptisITabletManager(__deref_out IUnknown** ppTabletManagerUnknown) +{ + return ::CoCreateInstance(CLSID_TabletManagerS, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_IUnknown, (LPVOID*)ppTabletManagerUnknown); +} + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcSurrogate.h b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcSurrogate.h new file mode 100644 index 00000000000..6b88b436ce7 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcSurrogate.h @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// PimcSurrogate.h : Declaration of the CPimcSurrogate + +#pragma once +#include "resource.h" // main symbols +#include "PenImc.h" + +///////////////////////////////////////////////////////////////////////////// +// CPimcSurrogate +class ATL_NO_VTABLE CPimcSurrogate : + public CComObjectRootEx, + public CComCoClass, + public IPimcSurrogate3 +{ +public: + + ///////////////////////////////////////////////////////////////////////// + + CPimcSurrogate(); + + HRESULT FinalConstruct(); + void FinalRelease(); + + // + // IPimcSurrogate3 + // + STDMETHOD(GetWisptisITabletManager)(__deref_out IUnknown** ppTabletManagerUnknown); + + // wiring + DECLARE_REGISTRY_RESOURCEID(IDR_PIMCSURROGATE) + + BEGIN_COM_MAP(CPimcSurrogate) + COM_INTERFACE_ENTRY(IPimcSurrogate3) + END_COM_MAP() + + DECLARE_PROTECT_FINAL_CONSTRUCT() +}; + +///////////////////////////////////////////////////////////////////////////// + +OBJECT_ENTRY_AUTO(__uuidof(PimcSurrogate3), CPimcSurrogate) + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcTablet.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcTablet.cpp new file mode 100644 index 00000000000..1cb2d9f4901 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcTablet.cpp @@ -0,0 +1,961 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// PimcTablet.cpp : Implementation of CPimcTablet + +#include "stdafx.h" +#include "PimcContext.h" +#include "PimcTablet.h" +#include +#include + +using namespace ComUtils; + +#if WANT_PROFILING +const INT s_cGuidsProfiling = 2; +#endif // WANT_PROFILING +const INT s_cGuids = 5; +GUID s_guids[s_cGuids] = { + {0x598A6A8F, 0x52C0, 0x4BA0, 0x93, 0xAF, 0xAF, 0x35, 0x74, 0x11, 0xA5, 0x61}, // GUID_X + {0xB53F9F75, 0x04E0, 0x4498, 0xA7, 0xEE, 0xC3, 0x0D, 0xBB, 0x5A, 0x90, 0x11}, // GUID_Y + {0x6E0E07BF, 0xAFE7, 0x4CF7, 0x87, 0xD1, 0xAF, 0x64, 0x46, 0x20, 0x84, 0x18}, // GUID_PACKETSTATUS + {0x39143d3, 0x78cb, 0x449c, 0xa8, 0xe7, 0x67, 0xd1, 0x88, 0x64, 0xc3, 0x32}, // GUID_TIPBUTTON + {0xf0720328, 0x663b, 0x418f, 0x85, 0xa6, 0x95, 0x31, 0xae, 0x3e, 0xcd, 0xfa} // GUID_BARRELBUTTON +}; + +// s_guids is used as is in some places as TABLET_CONTEXT_SETTINGS->pguidPktProps. +// NormalPressure is an optional property and should not be included in s_guids array +// as a generic entry. Hence a separate constant. +static const GUID GUID_NORMALPRESSURE = {0x7307502D, 0xF9F4, 0x4E18, {0xB3, 0xF2, 0x2C, 0xE1, 0xB1, 0xA3, 0x61, 0x0C}}; + +typedef enum GUID_INDEXES +{ + GUID_X = 0, + GUID_Y, + GUID_PACKETSTATUS, + GUID_TIPBUTTON, + GUID_BARRELBUTTON +} GUID_INDEXES; + + +// Fake Mouse Device constants +static const WCHAR* MOUSEDEVICE_CURSOR_NAME = L"Mouse"; +static const WCHAR* MOUSEDEVICE_BUTTON_ONE_NAME = L"Tip Switch"; +static const WCHAR* MOUSEDEVICE_BUTTON_TWO_NAME = L"Barrel Switch"; +static const WCHAR* MOUSEDEVICE_PLUGANDPLAYID = L"SCREEN"; + +static void EnsureNoDuplicateGUIDs(__in GUID *pGUID, __inout ULONG &cGUID) +{ + ULONG iIndex = 0; + + // Move all the unique guids to the beginning of the buffer. + for (ULONG i = 0; i < cGUID; i++) + { + ULONG j = 0; + for (; j < iIndex; j++) + { + if (pGUID[i] == pGUID[j]) + { + break; + } + } + if (j == iIndex) + { + pGUID[iIndex++] = pGUID[i]; + } + } + + // Set empty guid at left over spots + for (ULONG i = iIndex; i < cGUID; i++) + { + pGUID[i] = GUID_NULL; + } + + // Fix the count + cGUID = iIndex; +} + +// Helper routine to remove duplicate entries from TABLET_CONTEXT_SETTINGS' +// pguidPktProps and pguidPktBtns +static void EnsureNoDuplicates(__in TABLET_CONTEXT_SETTINGS * pTCS) +{ + EnsureNoDuplicateGUIDs(pTCS->pguidPktProps, pTCS->cPktProps); + EnsureNoDuplicateGUIDs(pTCS->pguidPktBtns, pTCS->cPktBtns); +} + +// Helper routine to sort TABLET_CONTEXT_SETTINGS->pguidPktProps such that +// X, Y and NormalPressure are always at the beginning in that order. +static void EnsureXYPressureOrder(__in TABLET_CONTEXT_SETTINGS * pTCS) +{ + bool bFoundX = FALSE; + bool bFoundY = FALSE; + bool bFoundPressure = FALSE; + + ULONG iIncreament = 0; + // Guard against integer underflow + if (pTCS->cPktProps > 0) + { + ULONG i = pTCS->cPktProps-1; + do { + if (pTCS->pguidPktProps[i] == s_guids[GUID_X]) + { + bFoundX = TRUE; + iIncreament++; + } + else if (pTCS->pguidPktProps[i] == s_guids[GUID_Y]) + { + bFoundY = TRUE; + iIncreament++; + } + else if (pTCS->pguidPktProps[i] == GUID_NORMALPRESSURE) + { + bFoundPressure = TRUE; + iIncreament++; + } + else + { + // Move other guids to right by an index equal to number of + // guids among X,Y and NormalPressure encountered so far. + pTCS->pguidPktProps[i + iIncreament] = pTCS->pguidPktProps[i]; + } + } while (i-- > 0); + } + + // Set X, Y and NormalPressure at their appropriate indices. + if (bFoundPressure) + { + pTCS->pguidPktProps[--iIncreament] = GUID_NORMALPRESSURE; + } + if (bFoundY) + { + pTCS->pguidPktProps[--iIncreament] = s_guids[GUID_Y]; + } + if (bFoundX) + { + pTCS->pguidPktProps[--iIncreament] = s_guids[GUID_X]; + } +} + +///////////////////////////////////////////////////////////////////////////// +// CPimcTablet + +///////////////////////////////////////////////////////////////////////////// + +CPimcTablet::CPimcTablet() +{ + m_cCursors = 0; + m_apCursorInfo = NULL; + m_pTCS = NULL; + m_pMgr = NULL; +} + +///////////////////////////////////////////////////////////////////////////// + +HRESULT CPimcTablet::Init(__in CComPtr pTabS, __in CComPtr pMgr) +{ + DHR; + m_pMgr = pMgr; + m_pTabS = pTabS; + + // Ensure the WISP tablet is stored in the GIT. + m_wispTabletLock = GitComLockableWrapper(m_pTabS, ComApartmentVerifier::Mta()); + CHR(m_wispTabletLock.CheckCookie()); + + // Prefetch packet description info so we don't have to call wisp later for it. + // This avoids reentrancy issues with doing an Out Of Proc COM call. + INT cProps, cButtons; + CHR(GetPacketDescriptionInfo(&cProps, &cButtons)); + CHR(RefreshCursorInfo()); +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +void CPimcTablet::FinalRelease() +{ + m_pMgr = nullptr; + m_pTabS = nullptr; + + ReleaseCursorInfo(); + ReleasePacketDescription(); + + m_wispTabletLock.RevokeIfValid(); +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::CreateContext(__typefix(HWND) __in INT_PTR pwnd, BOOL fEnable, UINT uiTimeout, __deref_out IPimcContext3** ppCtx, __out INT * pId, __out INT64 *pCommHandle) +{ + // pCommHandle cannot be a INT_PTR. The reason being that INT_PTR (__int3264) always gets + // marshalled as a 32 bit value, which means in a 64 bit process we would lose the first half of the pointer + // by the time it reaches the client. Instead this way we always pass a 64 bit value to the client + // (irrespective of process bitness) so that nothing gets lost during marshalling. + + DHR; + HWND hwnd = (HWND)pwnd; + CComPtr pCtxS; + CComObject * pCtxC; + TABLET_CONTEXT_ID tcid; + DWORD dwOptions = TCXO_CURSOR_STATE | TCXO_ALLOW_FLICKS | TCXO_ALLOW_FEEDBACK_TAPS | TCXO_ALLOW_FEEDBACK_BARREL | TCXO_REPORT_RECT_MAPPING_CHANGE; + PACKET_DESCRIPTION * pPacketDescription = NULL; + TABLET_CONTEXT_SETTINGS * pTCS = nullptr; + + // Make sure we use the default context settings if not already created. + if (m_pTabS && !m_pTCS) + { + CHR(m_pTabS->GetDefaultContextSettings(&m_pTCS)); + EnsureNoDuplicates(m_pTCS); + EnsureXYPressureOrder(m_pTCS); + CHR(m_pTCS ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_GETDEFAULTCONTEXT_CALL)); + } + + pTCS = m_pTCS; // NULL; + + CHR(IsWindow(hwnd) ? S_OK : E_INVALIDARG); + +#if WANT_PROFILE + if (m_pMgr->IsProfiling()) + { + CHR(m_pTabS->GetDefaultContextSettings(&pTCS)); + + CoTaskMemFree(pTCS->pguidPktProps); + CoTaskMemFree(pTCS->pguidPktBtns); + CoTaskMemFree(pTCS->pdwBtnDnMask); + CoTaskMemFree(pTCS->pdwBtnUpMask); + + pTCS->cPktProps = s_cGuidsProfiling; + pTCS->pguidPktProps = s_guids; + pTCS->cPktBtns = 0; + pTCS->pguidPktBtns = NULL; + pTCS->pdwBtnDnMask = NULL; + pTCS->pdwBtnUpMask = NULL; + + dwOptions = TCXO_DONT_VALIDATE_TCS | TCXO_DONT_SHOW_CURSOR; + } +#endif // WANT_PROFILING + + CHR(CComObject::CreateInstance(&pCtxC)); + CHR(pCtxC->QueryInterface(IID_IPimcContext3, (void**)ppCtx)); + + if (m_pTabS) + { + CHR(m_pTabS->CreateContext( + hwnd, // hwnd + NULL, // rc + dwOptions, // options + pTCS, // tablet context settings + fEnable ? CONTEXT_ENABLE : + CONTEXT_DISABLE, // enable type + &pCtxS, // the ctx + &tcid, // context id + &pPacketDescription, // packet description + (ITabletEventSink*)pCtxC->m_sink // sink + )); + + CHR(pCtxC->Init(m_pMgr, pCtxS, hwnd, tcid, pPacketDescription)); + pPacketDescription = NULL; // transfered ownership to the context + CHR(pCtxC->GetKey(pId)); // really just grabs tcid so could avoid call but would have to add param validation. + CHR(pCtxC->SetSingleFireTimeout(uiTimeout)); + CHR(pCtxC->GetCommHandle(pCommHandle)); // This adds a ref to keep pCtxC alive. + } + else + { + //need to fill in the context /// + pPacketDescription = (PACKET_DESCRIPTION *)CoTaskMemAlloc (sizeof(PACKET_DESCRIPTION)); + CHR_MEMALLOC(pPacketDescription); + + // Fill in the packet properties. + pPacketDescription->cbPacketSize = 3; + pPacketDescription->cPacketProperties = 3; + pPacketDescription->pPacketProperties = (PACKET_PROPERTY *)CoTaskMemAlloc (sizeof(PACKET_PROPERTY) * pPacketDescription->cbPacketSize); + CHR_MEMALLOC(pPacketDescription->pPacketProperties); + + // X + pPacketDescription->pPacketProperties[0].guid = s_guids[GUID_X]; + pPacketDescription->pPacketProperties[0].PropertyMetrics.nLogicalMin = LONG_MIN; + pPacketDescription->pPacketProperties[0].PropertyMetrics.nLogicalMax = LONG_MAX; + pPacketDescription->pPacketProperties[0].PropertyMetrics.Units = PROPERTY_UNITS_DEFAULT; + pPacketDescription->pPacketProperties[0].PropertyMetrics.fResolution = 1.0f; + + // Y + pPacketDescription->pPacketProperties[1].guid = s_guids[GUID_Y]; + pPacketDescription->pPacketProperties[1].PropertyMetrics.nLogicalMin = LONG_MIN; + pPacketDescription->pPacketProperties[1].PropertyMetrics.nLogicalMax = LONG_MAX; + pPacketDescription->pPacketProperties[1].PropertyMetrics.Units = PROPERTY_UNITS_DEFAULT; + pPacketDescription->pPacketProperties[1].PropertyMetrics.fResolution = 1.0f; + + // PacketStatus + pPacketDescription->pPacketProperties[2].guid = s_guids[GUID_PACKETSTATUS]; + pPacketDescription->pPacketProperties[2].PropertyMetrics.nLogicalMin = LONG_MIN; + pPacketDescription->pPacketProperties[2].PropertyMetrics.nLogicalMax = LONG_MAX; + pPacketDescription->pPacketProperties[2].PropertyMetrics.Units = PROPERTY_UNITS_DEFAULT; + pPacketDescription->pPacketProperties[2].PropertyMetrics.fResolution = 1.0f; + + // Fill in button data.... + pPacketDescription->cButtons = 2; + pPacketDescription->pguidButtons = (GUID *)CoTaskMemAlloc (sizeof(GUID)*2); + CHR_MEMALLOC(pPacketDescription->pguidButtons); + pPacketDescription->pguidButtons[0] = s_guids[GUID_TIPBUTTON]; + pPacketDescription->pguidButtons[1] = s_guids[GUID_BARRELBUTTON]; + + CHR(UIntPtrToULong(pwnd, &tcid)); + CHR(pCtxC->Init(m_pMgr, pCtxS, hwnd, tcid, pPacketDescription)); + pPacketDescription = NULL; // transfered ownership to the context + CHR(pCtxC->GetKey(pId)); + // These calls are really not neccessary for mouse context. + CHR(pCtxC->SetSingleFireTimeout(uiTimeout)); + CHR(pCtxC->GetCommHandle(pCommHandle)); // This adds a ref to keep pCtxC alive. + } + +CLEANUP: + if (pPacketDescription) + { + CPimcContext::DestroyPacketDescription(pPacketDescription); + } + + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetKey(__out INT * pKey) +{ + DHR; + CHR(pKey ? S_OK : E_INVALIDARG); + *pKey = (INT)PtrToInt(m_pTabS.p); +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetName(__out LPWSTR * ppszName) +{ + DHR; + LPWSTR pszNameCpy = NULL; + HMONITOR hMonitor = nullptr; + CHR(ppszName ? S_OK : E_INVALIDARG); + *ppszName = NULL; + + if (m_pTabS) + { + // We ignore the result code because otherwise we will throw a COM exception + // Invalid name does not mean invalid device. + if (!SUCCEEDED(m_pTabS->GetName(ppszName))) + { + // Do not rely on failure = null behavior of underlying COM component. + // We define failure = NULL here explicitly. + ppszName = NULL; + } + goto CLEANUP; + } + + // This is the same code that wisptis uses to determine the name of the Mouse device. + // Since this is a not very common called API we don't cache the name. + MONITORINFOEX MonitorInfoEx; + MonitorInfoEx.cbSize = SIZEOFSTRUCT(MonitorInfoEx); + hMonitor = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY); + CHR(hMonitor != NULL ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_MONITORFROMWINDOW_CALL)); + CHR(GetMonitorInfo(hMonitor, &MonitorInfoEx) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_GETMONITORINFO_CALL)); + + size_t cbName; + CHR(StringCchLengthW(MonitorInfoEx.szDevice, STRSAFE_MAX_CCH, &cbName)); + CHR(SizeTAdd(cbName, 1, &cbName)); + CHR(SizeTMult(cbName, sizeof(WCHAR), &cbName)); + pszNameCpy = (LPWSTR)CoTaskMemAlloc (cbName); + CHR_MEMALLOC(pszNameCpy); + CHR(StringCbCopy(pszNameCpy, cbName, MonitorInfoEx.szDevice)); + + *ppszName = pszNameCpy; + pszNameCpy = NULL; + +CLEANUP: + if (pszNameCpy != NULL) + { + ::CoTaskMemFree(pszNameCpy); + } + RHR +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetPlugAndPlayId(__out LPWSTR * ppszPlugAndPlayId) +{ + DHR; + if (m_pTabS) + return m_pTabS->GetPlugAndPlayId(ppszPlugAndPlayId); + else + { + // mousetab.cpp in wisptis is hard coded to return "SCREEN" for the mouse device. + size_t cbName; + CHR(StringCchLength(MOUSEDEVICE_PLUGANDPLAYID, STRSAFE_MAX_CCH, &cbName)); + CHR(SizeTAdd(cbName, 1, &cbName)); + CHR(SizeTMult(cbName, sizeof(WCHAR), &cbName)); + + *ppszPlugAndPlayId = (LPWSTR)CoTaskMemAlloc (cbName); + CHR_MEMALLOC(*ppszPlugAndPlayId); + return StringCbCopy(*ppszPlugAndPlayId, cbName, MOUSEDEVICE_PLUGANDPLAYID); + } + CLEANUP: + RHR +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetTabletAndDisplaySize(__out INT * piTabletWidth, __out INT * piTabletHeight, __out INT * piDisplayWidth, __out INT * piDisplayHeight) +{ + DHR; + RECT rcTablet = {0,0,0,0}; + CHR(piTabletWidth ? S_OK : E_INVALIDARG); + CHR(piTabletHeight ? S_OK : E_INVALIDARG); + CHR(piDisplayWidth ? S_OK : E_INVALIDARG); + CHR(piDisplayHeight ? S_OK : E_INVALIDARG); + + if (m_pTabS) + { + // First get tablet info... + CHR(m_pTabS->GetMaxInputRect(&rcTablet)); + *piTabletWidth = rcTablet.right - rcTablet.left; + *piTabletHeight = rcTablet.bottom - rcTablet.top; + + // Now get the display info... + + // First see if we have Vista wisptis that supports the new method + // that supports mapping integrated digitizers to displays. + CComQIPtr spTablet2(m_pTabS); + if (nullptr != spTablet2) + { + RECT rcScreen; + CHR(spTablet2->GetMatchingScreenRect(&rcScreen)); + *piDisplayWidth = rcScreen.right - rcScreen.left; + *piDisplayHeight = rcScreen.bottom - rcScreen.top; + goto CLEANUP; // we're done. + } + + // otherwise figure things out using the XP logic which maps to primary monitor + // always for integrated digitizers. + int iHwCaps = 0; + CHR(GetHardwareCaps(&iHwCaps)); + + // See if we are integrated. + if ((iHwCaps & THWC_INTEGRATED) != 0) + { + // integrated, so use primary monitor rect. + HMONITOR hMonitor = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY); + if (hMonitor != NULL) + { + MONITORINFOEX monitorInfo; + monitorInfo.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &monitorInfo); + *piDisplayWidth = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left; + *piDisplayHeight = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top; + goto CLEANUP; + } + } + + // If we fail above then just do non integrated code. + // non integrated so use desktop rect. + *piDisplayWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); + *piDisplayHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); + } + else + { + // By default just return same for tablet and display (no scaling). + *piTabletWidth = *piDisplayWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); + *piTabletHeight = *piDisplayHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); + } + +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetHardwareCaps(__out INT * pCaps) +{ + DHR; + DWORD dwCaps; + CHR(pCaps ? S_OK : E_INVALIDARG); + if (m_pTabS) + { + CHR(m_pTabS->GetHardwareCaps(&dwCaps)); + *pCaps = (INT)dwCaps; + } + else + { + // return the data for our 'fake mouse' + *pCaps = (INT)0x2; //StylusMustTouch + } +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////// +STDMETHODIMP CPimcTablet::GetDeviceType(__out INT * pKind) +{ + HRESULT hr = S_OK; + LPWSTR pszName = NULL; + CHR(pKind ? S_OK : E_INVALIDARG); + *pKind = 0; + + if (m_pTabS) + { + CComQIPtr spTablet2(m_pTabS); + if (nullptr != spTablet2) + { + TABLET_DEVICE_KIND kind; + hr = spTablet2->GetDeviceKind(&kind); + if (SUCCEEDED(hr)) + { + *pKind = (INT)kind; + goto CLEANUP; + } + } + } + + hr = GetName(&pszName); + if (SUCCEEDED(hr)) + { + *pKind = (NULL == wcsstr(pszName, L"\\\\.\\DISPLAY") ? 1 /*Pen*/: 0 /*Mouse*/); + } + +CLEANUP: + ::CoTaskMemFree(pszName); + RHR; +} + + + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::RefreshCursorInfo() +{ + DHR; + CComPtr pCursorS; + CComPtr pButtonS; + + ReleaseCursorInfo(); + + if (m_pTabS) + { + CHR(m_pTabS->GetCursorCount(&m_cCursors)); + m_apCursorInfo = new PCURSORINFO[m_cCursors](); + + CHR(m_apCursorInfo ? S_OK : E_OUTOFMEMORY); + + for (DWORD iCursor = 0; iCursor < m_cCursors; iCursor++) + { + CHR(m_pTabS->GetCursor(iCursor, &pCursorS)); + + PCURSORINFO pCursorInfo = new CURSORINFO(); + CHR(pCursorInfo ? S_OK : E_OUTOFMEMORY); + #pragma prefast( suppress: 11, "Dereferencing NULL pointer 'm_apCursorInfo'." ) + m_apCursorInfo[iCursor] = pCursorInfo; + + CHR(pCursorS->GetName(&pCursorInfo->pszName)); + CHR(pCursorS->GetId (&pCursorInfo->id)); + HRESULT hrInverted = pCursorS->IsInverted(); + CHR(hrInverted); + pCursorInfo->fInverted = hrInverted == S_OK; + + DWORD cButtons; + CHR(pCursorS->GetButtonCount(&cButtons)); + pCursorInfo->cButtons = cButtons; + pCursorInfo->apButtonInfo = new PCURSORBUTTONINFO[cButtons](); + + for (DWORD iButton = 0; iButton < cButtons; iButton++) + { + CHR(pCursorS->GetButton(iButton, &pButtonS)); + + PCURSORBUTTONINFO pButtonInfo = new CURSORBUTTONINFO(); + CHR(pButtonInfo ? S_OK : E_OUTOFMEMORY); + #pragma prefast( suppress: 11, "Dereferencing NULL pointer 'pCursorInfo'." ) + pCursorInfo->apButtonInfo[iButton] = pButtonInfo; + + CHR(pButtonS->GetName(&pButtonInfo->pszName)); + CHR(pButtonS->GetGuid(&pButtonInfo->guid)); + + // The smart pointer should be smart enough. + #pragma prefast( suppress: 416, "Dereferencing NULL smart pointer 'pButtonS'." ) + pButtonS = nullptr; + } + + pCursorS = nullptr; + } + } + else + { + // fake it up for a mouse... + m_cCursors = 1; + m_apCursorInfo = new PCURSORINFO[m_cCursors](); + CHR(m_apCursorInfo ? S_OK : E_OUTOFMEMORY); + + PCURSORINFO pCursorInfo = new CURSORINFO(); + CHR(pCursorInfo ? S_OK : E_OUTOFMEMORY); + #pragma prefast( suppress: 11, "Dereferencing NULL pointer 'm_apCursorInfo'." ) + m_apCursorInfo[0] = pCursorInfo; + + + size_t cbName; + CHR(StringCchLength(MOUSEDEVICE_CURSOR_NAME, STRSAFE_MAX_CCH, &cbName)); + CHR(SizeTAdd(cbName, 1, &cbName)); + CHR(SizeTMult(cbName, sizeof(WCHAR), &cbName)); + + pCursorInfo->pszName = (LPWSTR)CoTaskMemAlloc (cbName); + CHR_MEMALLOC(pCursorInfo->pszName); + StringCbCopy(pCursorInfo->pszName, cbName, MOUSEDEVICE_CURSOR_NAME); + + pCursorInfo->id = 1; // default for mouse device + pCursorInfo->fInverted = false; + + int cButtons = 2; // there are two buttons for a mouse... + pCursorInfo->cButtons = cButtons; + pCursorInfo->apButtonInfo = new PCURSORBUTTONINFO[cButtons](); + + //Get some memory for the button info... + for(int i=0; ipszName = (LPWSTR)CoTaskMemAlloc (cbName); + CHR_MEMALLOC(pButtonInfo->pszName); + StringCbCopy(pButtonInfo->pszName, cbName, MOUSEDEVICE_BUTTON_ONE_NAME); + pButtonInfo->guid = s_guids[GUID_TIPBUTTON]; + } + else + { + CHR(StringCchLength(MOUSEDEVICE_BUTTON_TWO_NAME, STRSAFE_MAX_CCH, &cbName)); + CHR(SizeTAdd(cbName, 1, &cbName)); + CHR(SizeTMult(cbName, sizeof(WCHAR), &cbName)); + + pButtonInfo->pszName = (LPWSTR)CoTaskMemAlloc (cbName); + CHR_MEMALLOC(pButtonInfo->pszName); + StringCbCopy(pButtonInfo->pszName, cbName, MOUSEDEVICE_BUTTON_TWO_NAME); + pButtonInfo->guid = s_guids[GUID_BARRELBUTTON]; + } + pCursorInfo->apButtonInfo[i] = pButtonInfo; + } + } + +CLEANUP: + + if ( FAILED(hr) ) + { + ReleaseCursorInfo(); + } + + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +void CPimcTablet::ReleaseCursorInfo() +{ + if (m_cCursors > 0) + { + if (nullptr != m_apCursorInfo) + { + for (DWORD iCursor = 0; iCursor < m_cCursors; iCursor++) + { + if (nullptr != m_apCursorInfo[iCursor]) + { + m_apCursorInfo[iCursor]->Clear(); + delete m_apCursorInfo[iCursor]; + m_apCursorInfo[iCursor] = nullptr; + } + } + delete [] m_apCursorInfo; + m_apCursorInfo = nullptr; + } + m_cCursors = 0; + } +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetCursorCount(__out INT * pcCursors) +{ + DHR; + CHR(pcCursors ? S_OK : E_INVALIDARG); + *pcCursors = m_cCursors; +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetCursorInfo(INT iCursor, __out LPWSTR * ppszName, __out INT * pId, __out BOOL * pfInverted) +{ + size_t cbName; + PCURSORINFO pCursorInfo = nullptr; + DHR; + + CHR(iCursor >= 0 ? S_OK : E_INVALIDARG); + CHR((DWORD)iCursor < m_cCursors ? S_OK : E_INVALIDARG); + CHR(ppszName ? S_OK : E_INVALIDARG); + CHR(pId ? S_OK : E_INVALIDARG); + CHR(pfInverted ? S_OK : E_INVALIDARG); + + // iCursor value is checked above, disable prefast signedness warning +#pragma prefast(suppress: 37001 37002 37003) + pCursorInfo = m_apCursorInfo[iCursor]; + CHR(StringCchLength(pCursorInfo->pszName, STRSAFE_MAX_CCH, &cbName)); + CHR(SizeTAdd(cbName, 1, &cbName)); + CHR(SizeTMult(cbName, sizeof(WCHAR), &cbName)); + *ppszName = (LPWSTR)CoTaskMemAlloc (cbName); + CHR_MEMALLOC(*ppszName); + StringCbCopy(*ppszName, cbName, pCursorInfo->pszName); + + *pId = pCursorInfo->id; + *pfInverted = pCursorInfo->fInverted; + +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetCursorButtonCount(INT iCursor, __out INT * pcButtons) +{ + DHR; + + switch (iCursor) + { + case LOCK_TABLET_EXT: + { + // DDVSO:514949 + // Calling this ensures that the CStdIdentity for this IPimcTablet3 is + // not released if we hit a COM rundown due to OSGVSO:10779198. + m_tabletLock = ComLockableWrapper(this, ComApartmentVerifier::CurrentSta()); + CHR(m_tabletLock.Lock()); + } + break; + case RELEASE_TABLET_EXT: + { + CHR(m_tabletLock.Unlock()); + } + break; + case QUERY_WISP_TABLET_KEY: + { + if (nullptr == pcButtons) + { + CHR(E_INVALIDARG); + } + else + { + *pcButtons = m_wispTabletLock.GetCookie(); + } + } + break; + case QUERY_WISP_MANAGER_KEY: + { + if (nullptr == pcButtons) + { + CHR(E_INVALIDARG); + } + else + { + *pcButtons = m_pMgr->m_wispManagerLock.GetCookie(); + } + } + break; + default: + { + CHR(GetCursorButtonCountImpl(iCursor, pcButtons)); + } + } + +CLEANUP: + RHR; +} + +STDMETHODIMP CPimcTablet::GetCursorButtonCountImpl(INT iCursor, __out INT * pcButtons) +{ + DHR; + CHR(iCursor >= 0 ? S_OK : E_INVALIDARG); + CHR((DWORD)iCursor < m_cCursors ? S_OK : E_INVALIDARG); + CHR(pcButtons ? S_OK : E_INVALIDARG); + // iCursor value is checked above, disable prefast signedness warning +#pragma prefast(suppress: 37001 37002 37003) + *pcButtons = m_apCursorInfo[iCursor]->cButtons; +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetCursorButtonInfo(INT iCursor, INT iButton, __out LPWSTR * ppszName, __out GUID * pGuid) +{ + DHR; + size_t cbName = 0; + LPWSTR pszNameSrc = nullptr; + PCURSORBUTTONINFO pButtonInfo = nullptr; + CHR(iCursor >= 0 ? S_OK : E_INVALIDARG); + CHR((DWORD)iCursor < m_cCursors ? S_OK : E_INVALIDARG); + CHR(iButton >= 0 ? S_OK : E_INVALIDARG); + + // iCursor is checked for underflow above, disable prefast signedness warnings +#pragma prefast(suppress: 37001 37002 37003) + CHR(iButton < m_apCursorInfo[iCursor]->cButtons ? S_OK : E_INVALIDARG); + CHR(ppszName ? S_OK : E_INVALIDARG); + CHR(pGuid ? S_OK : E_INVALIDARG); + + // iButton and iCursor are checked for underflow above, disable prefast signedness warnings +#pragma prefast(suppress: 37001 37002 37003) + pButtonInfo = m_apCursorInfo[iCursor]->apButtonInfo[iButton]; + + pszNameSrc = pButtonInfo->pszName; + CHR(StringCchLength(pszNameSrc, STRSAFE_MAX_CCH, &cbName)); + CHR(SizeTAdd(cbName, 1, &cbName)); + CHR(SizeTMult(cbName, sizeof(WCHAR), &cbName)); + *ppszName = (LPWSTR)CoTaskMemAlloc (cbName); + CHR_MEMALLOC(*ppszName); + StringCbCopy(*ppszName, cbName, pszNameSrc); + + *pGuid = pButtonInfo->guid; + +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::IsPropertySupported(GUID guid, __out BOOL * pfSupported) +{ + DHR; + CHR(pfSupported ? S_OK : E_INVALIDARG); + PROPERTY_METRICS metric; + *pfSupported = S_OK == m_pTabS->GetPropertyMetrics(guid, &metric); +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetPropertyInfo(GUID guid, __out INT * piMin, __out INT * piMax, __out INT * piUnit, __out FLOAT *pflResolution) +{ + DHR; + PROPERTY_METRICS metric; + CHR(piMin ? S_OK : E_INVALIDARG); + CHR(piMax ? S_OK : E_INVALIDARG); + CHR(piUnit ? S_OK : E_INVALIDARG); + CHR(pflResolution ? S_OK : E_INVALIDARG); + CHR(m_pTabS->GetPropertyMetrics(guid, &metric)); + *piMin = metric.nLogicalMin; + *piMax = metric.nLogicalMax; + *piUnit = metric.Units; + *pflResolution = metric.fResolution; +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetPacketDescriptionInfo(__out INT * pcProps, __out INT * pcButtons) +{ + DHR; + CHR(pcProps ? S_OK : E_INVALIDARG); + CHR(pcButtons ? S_OK : E_INVALIDARG); + + if (m_pTabS) + { + if (!m_pTCS) + { + CHR(m_pTabS->GetDefaultContextSettings(&m_pTCS)); + EnsureNoDuplicates(m_pTCS); + EnsureXYPressureOrder(m_pTCS); + CHR(m_pTCS ? S_OK : MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, E_GETDEFAULTCONTEXT_CALL)); + } + + *pcProps = m_pTCS->cPktProps; + *pcButtons = m_pTCS->cPktBtns; + } + else + { + // No wisptis case, so return mouse settings + *pcProps = 3; + *pcButtons = 2; + } + +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetPacketPropertyInfo(INT iProp, __out GUID * pGuid, __out INT * piMin, __out INT * piMax, __out INT * piUnits, __out FLOAT *pflResolution) +{ + DHR; + + CHR(0 <= iProp && (DWORD)iProp < (m_pTCS ? m_pTCS->cPktProps : 3) ? S_OK : E_INVALIDARG); + CHR(pGuid ? S_OK : E_INVALIDARG); + CHR(piMin ? S_OK : E_INVALIDARG); + CHR(piMax ? S_OK : E_INVALIDARG); + CHR(piUnits ? S_OK : E_INVALIDARG); + CHR(pflResolution ? S_OK : E_INVALIDARG); + + // iProp is checked for overflow/underflow above, disable prefast signedness warnings +#pragma prefast(suppress: 37001 37002 37003) + *pGuid = m_pTCS ? m_pTCS->pguidPktProps[iProp] : s_guids[iProp]; + *piMin = 0; // pProp->PropertyMetrics.nLogicalMin; + *piMax = 0; // pProp->PropertyMetrics.nLogicalMax; + *piUnits = 0; // pProp->PropertyMetrics.Units; + *pflResolution = 0.0f; // pProp->PropertyMetrics.fResolution; +CLEANUP: + RHR; +} + +///////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP CPimcTablet::GetPacketButtonInfo(INT iButton, __out GUID * pGuid) +{ + DHR; + CHR(0 <= iButton && (DWORD)iButton < (m_pTCS ? m_pTCS->cPktBtns : 2) ? S_OK : E_INVALIDARG); + CHR(pGuid ? S_OK : E_INVALIDARG); + + // Value of iButton is checked above. Since iButton is within known limits we assume the addition of 3 is accounted + // for and will not produce overflow. Disable prefast warnings +#pragma prefast(suppress: 37001 37002 37003) + *pGuid = m_pTCS ? + m_pTCS->pguidPktBtns[iButton] : // if we have context descr + s_guids[3+iButton]; // TipButton or BarrelButton equals index 3 or 4 +CLEANUP: + RHR; +} + + +///////////////////////////////////////////////////////////////////////////// + +void CPimcTablet::ReleasePacketDescription() +{ + if (m_pTCS) + { + if (m_pTCS->pguidPktProps) + CoTaskMemFree(m_pTCS->pguidPktProps); + if (m_pTCS->pguidPktBtns) + CoTaskMemFree(m_pTCS->pguidPktBtns); + if (m_pTCS->pdwBtnDnMask) + CoTaskMemFree(m_pTCS->pdwBtnDnMask); + if (m_pTCS->pdwBtnUpMask) + CoTaskMemFree(m_pTCS->pdwBtnUpMask); + + CoTaskMemFree(m_pTCS); + m_pTCS = NULL; + } +} + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcTablet.h b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcTablet.h new file mode 100644 index 00000000000..b9e6ecb5d44 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/PimcTablet.h @@ -0,0 +1,148 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// PimcTablet.h : Declaration of the CPimcTablet + +#pragma once +#include +#include "resource.h" // main symbols + +#include "PenImc.h" +#include "PimcManager.h" +#include "ComLockableWrapper.hpp" +#include "GitComLockableWrapper.hpp" + +///////////////////////////////////////////////////////////////////////////// +// CPimcTablet + +class ATL_NO_VTABLE CPimcTablet : + public CComObjectRootEx, + public CComCoClass, + public IPimcTablet3 +{ +public: + ///////////////////////////////////////////////////////////////////////// + + CPimcTablet(); + HRESULT FinalConstruct() { return S_OK; }; + void FinalRelease(); + + // DDVSO:174153 + // Cleanup initialization to use CComPtr throughout. This fixes COM reference count issues + // that arise due to conversion from round-tripping conversions from CComPtr to raw and back. + HRESULT Init(__in CComPtr pTabS, __in CComPtr pMgr); + void ReleaseCursorInfo(); + void ReleasePacketDescription(); + + STDMETHOD(GetKey)(__out INT * pKey); + STDMETHOD(GetName)(__out LPWSTR * ppszName); + STDMETHOD(GetPlugAndPlayId)(__out LPWSTR * ppszPlugAndPlayId); + STDMETHOD(GetTabletAndDisplaySize)(__out INT * piTabletWidth, __out INT * piTabletHeight, __out INT * piDisplayWidth, __out INT * piDisplayHeight); + STDMETHOD(GetHardwareCaps)(__out INT * pdwCaps); + STDMETHOD(GetDeviceType)(__out INT * pKind); + STDMETHOD(RefreshCursorInfo)(); + STDMETHOD(GetCursorCount)(__out INT * pcCursors); + STDMETHOD(GetCursorInfo)(INT iCursor, __out LPWSTR * ppszName, __out INT * pId, __out BOOL * pfInverted); + STDMETHOD(GetCursorButtonCount)(INT iCursor, __out INT * pcButtons); + STDMETHOD(GetCursorButtonCountImpl)(INT iCursor, __out INT * pcButtons); + STDMETHOD(GetCursorButtonInfo)(INT iCursor, INT iButton, __out LPWSTR * ppszName, __out GUID * pGuid); + STDMETHOD(IsPropertySupported)(GUID guid, __out BOOL * pfSupported); + STDMETHOD(GetPropertyInfo)(GUID guid, __out INT * piMin, __out INT * piMax, __out INT * piUnit, __out FLOAT *pflResolution); + STDMETHOD(CreateContext)(__typefix(HWND) __in INT_PTR pwnd, BOOL fEnable, UINT uiTimeout, __deref_out IPimcContext3** ppCtx, __out INT * pId, __out INT64 *pCommHandle); + STDMETHOD(GetPacketDescriptionInfo)(__out INT * pcProps, __out INT * pcButtons); + STDMETHOD(GetPacketPropertyInfo)(INT iProp, __out GUID * pGuid, __out INT * piMin, __out INT * piMax, __out INT * piUnits, __out FLOAT *pflResolution); + STDMETHOD(GetPacketButtonInfo)(INT iButton, __out GUID * pGuid); + + ///////////////////////////////////////////////////////////////////////// + +BEGIN_COM_MAP(CPimcTablet) + COM_INTERFACE_ENTRY(IPimcTablet3) +END_COM_MAP() + + DECLARE_PROTECT_FINAL_CONSTRUCT() + + ///////////////////////////////////////////////////////////////////////// + + struct CURSORBUTTONINFO + { + LPWSTR pszName; + GUID guid; + + CURSORBUTTONINFO() + { + pszName = nullptr; + ZeroMemory(&guid, sizeof(guid)); + } + + void Clear() + { + if (nullptr != pszName) + { + CoTaskMemFree(pszName); + pszName = nullptr; + } + } + }; + typedef CURSORBUTTONINFO * PCURSORBUTTONINFO; + + ///////////////////////////////////////////////////////////////////////// + + struct CURSORINFO + { + LPWSTR pszName; + CURSOR_ID id; + BOOL fInverted; + INT cButtons; + PCURSORBUTTONINFO * apButtonInfo; + + CURSORINFO() + { + pszName = nullptr; + id = 0; + fInverted = false; + cButtons = 0; + apButtonInfo = nullptr; + } + + void Clear() + { + if (nullptr != pszName) + { + CoTaskMemFree(pszName); + pszName = nullptr; + } + for (INT i = 0; i < cButtons; i++) + { + if (nullptr != apButtonInfo[i]) + { + apButtonInfo[i]->Clear(); + delete apButtonInfo[i]; + apButtonInfo[i] = nullptr; + } + } + delete [] apButtonInfo; + } + }; + typedef CURSORINFO * PCURSORINFO; + + ///////////////////////////////////////////////////////////////////////// + + CComPtr m_pMgr; + CComPtr m_pTabS; + ComUtils::GitComLockableWrapper m_wispTabletLock; + DWORD m_cCursors; + PCURSORINFO * m_apCursorInfo; + TABLET_CONTEXT_SETTINGS * m_pTCS; + ComUtils::ComLockableWrapper m_tabletLock; + + // DDVSO:514949 + // Special param flags for COM operations in GetCursorButtonCount + const static int RELEASE_TABLET_EXT = -1; + const static int QUERY_WISP_TABLET_KEY = -2; + const static int QUERY_WISP_MANAGER_KEY = -3; + const static int LOCK_TABLET_EXT = -4; +}; + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/SxSCOMRegistration.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/SxSCOMRegistration.cpp new file mode 100644 index 00000000000..0e97f1dded4 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/SxSCOMRegistration.cpp @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +#include "stdafx.h" +#include "peninc.h" + +EXTERN_C IMAGE_DOS_HEADER __ImageBase; + +// Creates an ActivationContext using the embedded manifest and pushes it on the +// context stack. The ActivationContext cookie is returned to the caller: a non-zero value +// indicates success; zero indicates failure. Caller is responsible for deactivating +// the context. +extern "C" ULONG_PTR WINAPI RegisterDllForSxSCOM() +{ + // Get the full path to this Dll + WCHAR moduleFullPath[MAX_PATH] = {0}; + if (!GetModuleFileNameW((HINSTANCE)&__ImageBase, moduleFullPath, _countof(moduleFullPath))) + { + return 0; + } + + // ACTCTX.lpResourceName must be 'ISOLATIONAWARE_MANIFEST_RESOURCE_ID' for Dlls. + // Defined as: ISOLATIONAWARE_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(2) + ACTCTX activationContext = {}; + activationContext.cbSize = sizeof(activationContext); + activationContext.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_APPLICATION_NAME_VALID; + activationContext.lpSource = moduleFullPath; + activationContext.lpResourceName = ISOLATIONAWARE_MANIFEST_RESOURCE_ID; + + // Create and activate context : context is added to the top of the context stack + HANDLE activationContextHandle = ::CreateActCtxW(&activationContext); + if (INVALID_HANDLE_VALUE == activationContextHandle) + { + return 0; + } + + ULONG_PTR activationContextCookie = 0; + BOOL activateActCtxResult = ::ActivateActCtx(activationContextHandle, &activationContextCookie); + if (activateActCtxResult == FALSE) + { + return 0; + } + + // Return the context cookie : caller is responsible for deactivating the context. + return activationContextCookie; +} + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/WispComLockExports.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/WispComLockExports.cpp new file mode 100644 index 00000000000..cb86b9c9cac --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/WispComLockExports.cpp @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +#include "stdafx.h" + +#include "ComApartmentVerifier.hpp" +#include "GitComLockableWrapper.hpp" + +using namespace ComUtils; + +// Exported call to lock WISP objects stored in the GIT +extern "C" BOOL WINAPI LockWispObjectFromGit(__in DWORD gitKey) +{ + GitComLockableWrapper git(gitKey, ComApartmentVerifier::Mta()); + HRESULT hr = git.Lock(); + + return SUCCEEDED(hr); +} + +// Exported call to unlock WISP objects stored in the GIT +extern "C" BOOL WINAPI UnlockWispObjectFromGit(__in DWORD gitKey) +{ + GitComLockableWrapper git(gitKey, ComApartmentVerifier::Mta()); + HRESULT hr = git.Unlock(); + + return SUCCEEDED(hr); +} diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/compressstub.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/compressstub.cpp new file mode 100644 index 00000000000..9ed8fcc1b9f --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/compressstub.cpp @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// compressstub.cpp : Implementation of compress.lib (and hopefully in +// the future shared.lib stubs) +// +// NOTE: Currently I could not directly export functions declared in a .lib +// file we link in so stubs have been created to which reference the .lib +// routines we want to use and thing then get resolved properly and we can +// then export these stubs (with a rename trick in the .def file). +// If we can figure out how to directly expose .lib functions then these +// stubs can be removed. + +#include "stdafx.h" +#include + +// Stubs to allow us to resolve to the compress.lib routines we want to expose from our +// DLL. + +extern "C" ISF_RESULT IsfCompressPropertyData_stub( + IN const BYTE * pbInput, // Input data + IN ULONG cbInput, // Number of bytes in buffer + IN OUT BYTE * pnAlgoByte, // in: desired alg. identifier byte, out: really the best + IN OUT ULONG * pcbOutput, // in: cb of the buffer; out: cb needed to compress + OUT BYTE * pbOutput // OUT, output buffer + ) +{ + return IsfCompressPropertyData(pbInput,cbInput,pnAlgoByte,pcbOutput,pbOutput); +} + +extern "C" ISF_RESULT IsfDecompressPropertyData_stub( + IN const BYTE * pbCompressed, // in, compressed input bytes + IN ULONG cbCompressed, // in: size of the input bytes + OUT ULONG * pcbOutput, // in: cb in pbOutput, out: required + OUT BYTE * pbOutput, // Uncompressed data + OUT BYTE * pnAlgoByte // Algorithm used + ) +{ + return IsfDecompressPropertyData(pbCompressed, cbCompressed, pcbOutput, pbOutput, pnAlgoByte); +} + +extern "C" ISF_RESULT IsfCompressPacketData_stub( + IN HCOMPRESS hCompress, // compressor handle, + IN const LONG * pbInput, // Input data, always LONG + IN ULONG cInCount, // Number of LONGs in buffer + IN OUT BYTE * pnAlgoByte, // in: preferred algo byte out: really the best + IN OUT ULONG * pcbOutput, // in: cb of the buffer; out: cb needed to compress + OUT BYTE * pbOutput // OUT, output buffer + ) +{ + return IsfCompressPacketData(hCompress, pbInput, cInCount, pnAlgoByte, pcbOutput, pbOutput); +} + +extern "C" ISF_RESULT IsfDecompressPacketData_stub( + IN HCOMPRESS hCompress, // Compressor handle + IN const BYTE * pbCompressed, // Compressed input bytes + IN OUT ULONG * pcbCompressed, // in: cb of the input bytes out: cb read + IN ULONG cInCount, // Number of elements in input buffer + OUT LONG * pbOutput, // Uncompressed data + OUT BYTE * pnAlgoData // Algorithm used + ) +{ + return IsfDecompressPacketData(hCompress, pbCompressed, pcbCompressed, cInCount, pbOutput, pnAlgoData); +} + +extern "C" HCOMPRESS IsfLoadCompressor_stub( + IN const BYTE * pbInput, + IN ULONG * pcbInput + ) +{ + return IsfLoadCompressor(pbInput, pcbInput); +} + + +extern "C" void IsfReleaseCompressor_stub(HCOMPRESS hCompress) +{ + IsfReleaseCompressor(hCompress); +} + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/dir.targets b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/dir.targets new file mode 100644 index 00000000000..5236e7c6faf --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/dir.targets @@ -0,0 +1,3 @@ + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/dlldatax.c b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/dlldatax.c new file mode 100644 index 00000000000..dee4aaa1c98 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/dlldatax.c @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// wrapper for dlldata.c + +#ifdef _MERGE_PROXYSTUB // merge proxy stub DLL + +#define REGISTER_PROXY_DLL //DllRegisterServer, etc. + +#define USE_STUBLESS_PROXY //defined only with MIDL switch /Oicf + +// 'rpcndr' is a deprecated lib; link to rpcns4.lib and rpcrt4.lib instead. +#pragma comment(lib, "rpcns4.lib") +#pragma comment(lib, "rpcrt4.lib") + +#define ENTRY_PREFIX Prx + +#include "dlldata.c" +#include + +#endif //_MERGE_PROXYSTUB + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/dlldatax.h b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/dlldatax.h new file mode 100644 index 00000000000..90a06ed9cc1 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/dlldatax.h @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +#pragma once + +#ifdef _MERGE_PROXYSTUB + +extern "C" +{ +BOOL WINAPI PrxDllMain(HINSTANCE hInstance, DWORD dwReason, + LPVOID lpReserved); +STDAPI PrxDllCanUnloadNow(void); +STDAPI PrxDllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv); +STDAPI PrxDllRegisterServer(void); +STDAPI PrxDllUnregisterServer(void); +} + +#endif + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/resource.h b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/resource.h new file mode 100644 index 00000000000..9ad9cc82b34 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/resource.h @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by PenImc.rc +// +#define IDS_PROJNAME 100 +#define IDR_PENIMC 101 +#define IDR_PIMCMANAGER 102 +#define IDR_PIMCSURROGATE 105 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 201 +#define _APS_NEXT_COMMAND_VALUE 32768 +#define _APS_NEXT_CONTROL_VALUE 201 +#define _APS_NEXT_SYMED_VALUE 106 +#endif +#endif + + +// Custom HRESULTS... +// +#define E_CREATEEVENT_CALL 0x301 +#define E_GETCURRENTPROCESSID_CALL 0x302 +#define E_QUEUEUSERAPC_CALL 0x303 +#define E_USESHAREDMEMORYCOM_CALL 0x304 +#define E_SHAREDMEMORYHEADER_NULL 0x305 +#define E_SHAREDMEMORYRAWDATA_NULL 0x306 +#define E_CANNOTCREATERESETEVENT 0x307 +#define E_GETDEFAULTCONTEXT_CALL 0x308 +#define E_MONITORFROMWINDOW_CALL 0x309 +#define E_GETMONITORINFO_CALL 0x310 + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/stdafx.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/stdafx.cpp new file mode 100644 index 00000000000..5ee5118c602 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/stdafx.cpp @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// stdafx.cpp : source file that includes just the standard includes +// PenImc.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/dll/stdafx.h b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/stdafx.h new file mode 100644 index 00000000000..f386cc075cf --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/dll/stdafx.h @@ -0,0 +1,91 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + +#ifndef STRICT +#define STRICT +#endif + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. +#define WINVER 0x0501 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target Windows XP or later. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. +#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later. +#endif + +///////////////////////////////////////////////////////////////////////////// + +#define _ATL_SINGLE_THREADED // #define _ATL_APARTMENT_THREADED // #define _ATL_FREE_THREADED + +#define _ATL_NO_AUTOMATIC_NAMESPACE + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +#define _ATL_ALL_WARNINGS // turns off ATL's hiding of some common and often safely ignored warning messages + +#include +#include "resource.h" +#include +#include + +using namespace ATL; + +#include + +#define WM_UNINITMENUPOPUP 0x0125 + +///////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +// #define DELIVERY_PROFILING // DO NOT LEAVE ENABLED in the checked in code + +#if 1 // from csutil.h //..WIP (alexz) proper includes +#define WISPTIS_SHAREDMEMORY_MAXPACKETS 64 + +#define WISPTIS_SHAREDMEMORY_AVAILABLE 0xFFFFFFFF + +struct SHAREDMEMORY_HEADER +{ + DWORD cbTotal; + DWORD cbOffsetSns; + + DWORD idxEvent; + DWORD dwEvent; + + CURSOR_ID cid; + DWORD sn; + SYSTEM_EVENT sysEvt; + SYSTEM_EVENT_DATA sysEvtData; + DWORD cPackets; + DWORD cbPackets; + BOOL fSnsPresent; + + void Clear() + { + INT cbUnclearable = 2 * sizeof(DWORD); + ZeroMemory(((BYTE*)this) + cbUnclearable, sizeof(*this) - cbUnclearable); + } +}; +#endif + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/TabAssert.h b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/TabAssert.h new file mode 100644 index 00000000000..a561cd43973 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/TabAssert.h @@ -0,0 +1,454 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +///////////////////////////////////////////////////////////////////////////// +// +// +// Module: +// TabAssert.h +// +// Description: +// To facilitate the debugging of Tablet Platform built binaries, we +// needed a common set of functionallity for ASSERTs and debug logging. +// This header file represents that collection of functionallity. +// +// Additionally, the testing team has requested the ability to turn +// off ASSERTs programmatically. +// +// +// Comments: +// +// Under HKEY_CLASSES_ROOT\TpgDebug, there are currently 8 values: +// +// AssertMode +// AssertFile +// DumpInfoMode +// DumpInfoFile +// FuncTraceMode +// FuncTraceFile +// HRFailMode +// HRFailFile +// +// These Modes are a bitwise OR of 3 possible values which correspond +// to the CRT Debug libraries definitions of +// +// _CRTDBG_MODE_FILE 0x1 (file) +// _CRTDBG_MODE_DEBUG 0x2 (trace window) +// _CRTDBG_MODE_WNDW 0x4 (dialog window) +// +// The File values (AssertFile, HRFailFile) are used if bit 0x1 is set +// for a corresponding Mode. +// +// In the default settings (if you've never modified your registry by +// hand or programatically), the values would be: +// +// AssertMode = 4 +// AssertFile = "C:\TPGDEBUG.LOG" +// DumpInfoMode = 2 +// DumpInfoFile = "C:\TPGDEBUG.LOG" +// FuncTraceMode = 0 +// FuncTraceFile = "C:\TPGDEBUG.LOG" +// HRFailMode = 2 +// HRFailFile = "C:\TPGDEBUG.LOG" +// +// This would result in Assert failures being displayed in a dialog window +// (because 0x4 is set in AssertMode and 0x4 corresponds to WNDW above). +// +// If you wanted to turn off the dialog window based asserts, but you still +// wanted them logged to a file and sent to the debugger output window, you +// could set AssertMode = 3 (which is 0x1 | 0x2, or written symbolically as +// FILE | DEBUG from above). +// +// Additionally, there is a fifth value under TpgDebug, called +// AssertSettingsReReadEachTime. This is a boolean value and is used in +// speical cases when the test team wants to programmatically change +// the AssertMode at runtime while the binaries are running. The default +// for this value is 0 and as such, all the TpgDebug registry settings +// are read at startup. If AssertSettingsReReadEachTime is set to 1, +// most of the TpgDebug values are read at startup, with the exception of +// AssertMode/AssertFile. This allows the testers to log the assert values +// to specific locations. Care should be used when enabling this setting, +// though, because this is a huge performance hit. +// +///////////////////////////////////////////////////////////////////////////// + +#pragma once + +#ifndef _TABASSERT_HEADER + +#include + +#include +#include +#include + +#if 0 // #ifdef DBG + +#ifdef __cplusplus +extern "C" { +#endif + +int WINAPI MyCrtSetReportMode( + int nRptType, + int fMode + ); + +_HFILE WINAPI MyCrtSetReportFile( + int nRptType, + _HFILE hFile + ); + +int WINAPI MyCrtDbgReportA( + int nRptType, + const char * szFile, + int nLine, + const char * szModule, + const char * szFormat, + ... + ); + +int WINAPI MyCrtDbgReportW( + int nRptType, + const WCHAR * wzFile, + int nLine, + const WCHAR * wzModule, + const WCHAR * wzFormat, + ... + ); + +void WINAPI MyCrtDbgBreak( + void + ); + +BOOL WINAPI TpgDebugAssertEnter(); +BOOL WINAPI TpgDebugAssertLeave(); +BOOL WINAPI TpgDebugDumpInfoEnter(); +BOOL WINAPI TpgDebugDumpInfoLeave(); +BOOL WINAPI TpgDebugFuncTraceEnter(); +BOOL WINAPI TpgDebugFuncTraceLeave(); +BOOL WINAPI TpgDebugHRFailEnter(); +BOOL WINAPI TpgDebugHRFailLeave(); + +int WINAPI DoTheAssert( + const char * pszFile, + int nLine, + const char * szExpr, + BOOL fHaveHR, + HRESULT hr + ); + +void WINAPI DoTheHRFail( + const char *pszFile, + int nLine, + HRESULT hr); + +#ifdef __cplusplus +} +#endif + + +#endif // DBG + +//=== User macros ============================================================== + +#if 0 // #ifdef DBG + +// Push current pragma settings +#pragma push + +// Turn off "conditional expression is constant" because of while(0). +#pragma warning ( disable : 4127 ) + +#if defined __cplusplus && !defined _PREFAST_ + +// Turn off "local variable 'hr' used without having been initialized" because of HRESULT hr; statements +#pragma warning ( disable : 4700 ) + +// C++ compatible assert that includes HR value. +#define TPDBG_ASSERTSZ(expr,szDescription) \ + do \ + { \ + if (!(expr)) \ + { \ + if (TpgDebugAssertEnter()) \ + { \ + static DWORD dwDisableAssert; \ + if (dwDisableAssert == 0) \ + { \ + __if_exists(hr) \ + { \ + int iRet = DoTheAssert( \ + __FILE__, \ + __LINE__, \ + szDescription, \ + TRUE, \ + hr ); \ + } \ + __if_not_exists(hr) \ + { \ + int iRet = DoTheAssert( \ + __FILE__, \ + __LINE__, \ + szDescription, \ + FALSE, \ + 0); \ + } \ + if (iRet == 1) \ + { \ + MyCrtDbgBreak(); \ + } \ + else if (iRet == 2) \ + { \ + dwDisableAssert = 1; \ + } \ + } \ + TpgDebugAssertLeave(); \ + } \ + } \ + } \ + while (0) + +#else + +// C compatible assert that does not includes HR value. +// Prefast compatible version (prefast also complains about uninitialized hr variables). +#define TPDBG_ASSERTSZ(expr,szDescription) \ + do \ + { \ + if (!(expr)) \ + { \ + if (TpgDebugAssertEnter()) \ + { \ + static DWORD dwDisableAssert; \ + if (dwDisableAssert == 0) \ + { \ + int iRet = DoTheAssert( \ + __FILE__, \ + __LINE__, \ + szDescription, \ + FALSE, \ + 0); \ + if (iRet == 1) \ + { \ + MyCrtDbgBreak(); \ + } \ + else if (iRet == 2) \ + { \ + dwDisableAssert = 1; \ + } \ + } \ + TpgDebugAssertLeave(); \ + } \ + } \ + } \ + while (0) + +#endif + +// Restore pragma settings. +#pragma pop + +#define TPDBG_ASSERT(expr) \ + TPDBG_ASSERTSZ(expr, #expr) + +#define TPDBG_VERIFY(expr) \ + TPDBG_ASSERT(expr) + +#ifdef ASSERT +#undef ASSERT +#endif // ASSERT + +#define ASSERT(expr) \ + TPDBG_ASSERT(expr) + +#ifdef ASSERTSZ +#undef ASSERTSZ +#endif // ASSERTSZ + +#define ASSERTSZ(expr, szDescription) \ + TPDBG_ASSERTSZ(expr, szDescription) + +#define TPDBG_RPT(rptno, msg) \ + do { if ((1 == MyCrtDbgReportW(rptno, NULL, 0, NULL, L"%s", msg))) \ + MyCrtDbgBreak(); } while (0) + +#define TPDBG_RPT0(rptno, msg) \ + do { if ((1 == MyCrtDbgReportA(rptno, NULL, 0, NULL, "%s", msg))) \ + MyCrtDbgBreak(); } while (0) + +#define TPDBG_RPT1(rptno, msg, arg1) \ + do { if ((1 == MyCrtDbgReportA(rptno, NULL, 0, NULL, msg, arg1))) \ + MyCrtDbgBreak(); } while (0) + +#define TPDBG_RPT2(rptno, msg, arg1, arg2) \ + do { if ((1 == MyCrtDbgReportA(rptno, NULL, 0, NULL, msg, arg1, arg2))) \ + MyCrtDbgBreak(); } while (0) + +#define TPDBG_RPT3(rptno, msg, arg1, arg2, arg3) \ + do { if ((1 == MyCrtDbgReportA(rptno, NULL, 0, NULL, msg, arg1, arg2, arg3))) \ + MyCrtDbgBreak(); } while (0) + +#define TPDBG_RPT4(rptno, msg, arg1, arg2, arg3, arg4) \ + do { if ((1 == MyCrtDbgReportA(rptno, NULL, 0, NULL, msg, arg1, arg2, arg3, arg4))) \ + MyCrtDbgBreak(); } while (0) + +void DMSG(WCHAR *wzformat, ...); + +#define TPDBG_DMSG0(format) \ + do \ + { \ + if (TpgDebugDumpInfoEnter()) \ + { \ + TPDBG_RPT0(_CRT_WARN, format); \ + TpgDebugDumpInfoLeave(); \ + } \ + } while (0) +#define TPDBG_DMSG1(format, arg1) \ + do \ + { \ + if (TpgDebugDumpInfoEnter()) \ + { \ + TPDBG_RPT1(_CRT_WARN, format, arg1); \ + TpgDebugDumpInfoLeave(); \ + } \ + } while (0) +#define TPDBG_DMSG2(format, arg1, arg2) \ + do \ + { \ + if (TpgDebugDumpInfoEnter()) \ + { \ + TPDBG_RPT2(_CRT_WARN, format, arg1, arg2); \ + TpgDebugDumpInfoLeave(); \ + } \ + } while (0) +#define TPDBG_DMSG3(format, arg1, arg2, arg3) \ + do \ + { \ + if (TpgDebugDumpInfoEnter()) \ + { \ + TPDBG_RPT3(_CRT_WARN, format, arg1, arg2, arg3); \ + TpgDebugDumpInfoLeave(); \ + } \ + } while (0) +#define TPDBG_DMSG4(format, arg1, arg2, arg3, arg4) \ + do \ + { \ + if (TpgDebugDumpInfoEnter()) \ + { \ + TPDBG_RPT4(_CRT_WARN, format, arg1, arg2, arg3, arg4); \ + TpgDebugDumpInfoLeave(); \ + } \ + } while (0) + +#define TPDBG_FUNC_ENTER(name) \ + do \ + { \ + if (TpgDebugFuncTraceEnter()) \ + { \ + TPDBG_RPT2(_CRT_WARN, "0x%x: Entering Function: %s\r\n", GetCurrentThreadId(), name); \ + TpgDebugFuncTraceLeave(); \ + } \ + } while (0) + +#define TPDBG_FUNC_LEAVE(name) \ + do \ + { \ + if (TpgDebugFuncTraceEnter()) \ + { \ + TPDBG_RPT2(_CRT_WARN, "0x%x: Leaving Function: %s\r\n", GetCurrentThreadId(), name); \ + TpgDebugFuncTraceLeave(); \ + } \ + } while (0) + +#ifdef __cplusplus + +class CTpgFuncTrace +{ +public: + + CTpgFuncTrace(char * pszFuncName) : m_pszFuncName(pszFuncName) { TPDBG_FUNC_ENTER(m_pszFuncName); } + ~CTpgFuncTrace() { TPDBG_FUNC_LEAVE(m_pszFuncName); } + +private: + char * m_pszFuncName; +}; + +#define TPDBG_FUNC(name) \ + CTpgFuncTrace functrace(name) + +#define DBGFUNC \ + CTpgFuncTrace functrace(__FUNCTION__) + +#endif // __cplusplus + + +#define TPDBG_REPORT_ON_FAIL(hr) \ + do \ + { \ + HRESULT _hr = (hr); \ + if (FAILED(_hr) && TpgDebugHRFailEnter()) \ + { \ + DoTheHRFail( \ + __FILE__, \ + __LINE__, \ + _hr); \ + TpgDebugHRFailLeave(); \ + } \ + } while (0) + +#define TPDBG_RETURN(hr) \ + { \ + HRESULT __hr = (hr); \ + if (FAILED(__hr)) \ + { \ + TPDBG_REPORT_ON_FAIL(__hr); \ + } \ + return __hr; \ + } + +#else // DBG + +#define TPDBG_ASSERT(expr) +#define TPDBG_VERIFY(expr) (expr) + +#ifdef ASSERT +#undef ASSERT +#endif // ASSERT + +#define ASSERT(expr) + +#ifdef ASSERTSZ +#undef ASSERTSZ +#endif //ASSERTSZ + +#define ASSERTSZ(expr, szDescription) + +#define TPDBG_RPT0(rptno, msg) +#define TPDBG_RPT1(rptno, msg, arg1) +#define TPDBG_RPT2(rptno, msg, arg1, arg2) +#define TPDBG_RPT3(rptno, msg, arg1, arg2, arg3) +#define TPDBG_RPT4(rptno, msg, arg1, arg2, arg3, arg4) + +#define TPDBG_DMSG0(format) +#define TPDBG_DMSG1(format, arg1) +#define TPDBG_DMSG2(format, arg1, arg2) +#define TPDBG_DMSG3(format, arg1, arg2, arg3) +#define TPDBG_DMSG4(format, arg1, arg2, arg3, arg4) + +#define TPDBG_FUNC_ENTER(name) +#define TPDBG_FUNC_LEAVE(name) + +#ifdef __cplusplus +#define TPDBG_FUNC(name) +#define DBGFUNC +#endif // __cplusplus + +#define TPDBG_REPORT_ON_FAIL(hr) +#define TPDBG_RETURN(hr) return (hr) + +#endif // DBG + +#endif //_TABASSERT_HEADER + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/TabInc.h b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/TabInc.h new file mode 100644 index 00000000000..55165579061 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/TabInc.h @@ -0,0 +1,114 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +#ifndef __TABINC_H_ +#define __TABINC_H_ + +#include + +////////////////////////////////////////////////////////////////////////////////////////////// +// +// SECURITY +// + +#define TPGSECURE(X, DEVELOPERS, REVIEW_DATE, EXPLANATION_WHY_SECURE) X + +// +// Example: +// +// pszFoo = new TCHAR[_tcslen(pszBar) + 1] +// _tcscpy(pszFoo, pszBar); +// change to: +// pszFoo = new TCHAR[_tcslen(pszBar) + 1] +// TPGSECURE(_tcscpy(pszFoo, pszBar), "JohnDoe", "2/12/2002", "pszFoo is allocated using length of pszBar"); +// + +////////////////////////////////////////////////////////////////////////////////////////////// +// +// HR and return value handling +// + +#define IGNORERESULT(result) (void)result + +// (using inlines for IGNOREHR, VERIFYHR, VERIFYBOOL to have type checking) + +_inline void IGNOREHR(HRESULT hr) +{ +hr; +} + +_inline void VERIFYHR(HRESULT hr) +{ + hr; +#ifdef DBG + ASSERT(SUCCEEDED(hr)); +#endif +} + +_inline void VERIFYBOOL(BOOL br) +{ + br; +#ifdef DBG + ASSERT(br); +#endif +} + +////////////////////////////////////////////////////////////////////////////////////////////// +// +// Additional String Primitives +// + +HRESULT StringAllocateWithNewAndCopy (__out LPTSTR * ppszDestination, __in LPTSTR pszSource); +HRESULT StringAllocateWithMallocAndCopy(__out LPTSTR * ppszDestination, __in LPTSTR pszSource); + +////////////////////////////////////////////////////////////////////////////////////////////// +// +// SAFE primitives +// + +#define ZEROSTRUCT(X) ZeroMemory(X, sizeof(*(X))) + +#define SIZEOFSZ(X) (sizeof(X[0]) * (_tcslen(X) + 1)) +#define SIZEOFSTRUCT(X) (sizeof(X)) +#define SIZEOFARRAY(X) (sizeof(X)) + +#define LENGTHOFARRAY(X) (sizeof(X) / sizeof(X[0])) + +////////////////////////////////////////////////////////////////////////////////////////////// + +// Not all of the projects that include tabinc.h use ole automation; +// so "BSTR" wouldn't be defined for them. We check here for "_OLEAUTO_H_" +// to determine if ole automation is used. For this reason, tabinc.h +// should be included after oleauto.h + +#ifdef _OLEAUTO_H_ + +BOOL IsBadReadBstr(BSTR bstr, BOOL fCheckForAndDisallowEmbeddedNulls); // implemented in tablib.cpp + +_inline BOOL IsBadWriteBstr(BSTR * pbstr) +{ + return FALSE; // Banned API -> IsBadWritePtr(pbstr, sizeof(*pbstr)); +} + +#endif + + +////////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////////// +// Macros and helpers for CRITICAL_SECTION + +#define TPG_INITIALIZE_CRITICAL_SECTION_PREALLOC(pCritSect) InitializeCriticalSectionAndSpinCount(pCritSect, (0x8001000 | 4000)) +#define TPG_INITIALIZE_CRITICAL_SECTION_NOPREALLOC(pCritSect) InitializeCriticalSectionAndSpinCount(pCritSect, (0x8000000 | 4000)) + +////////////////////////////////////////////////////////////////////////////////////////////// + +// closes the *pHandle, if it's not NULL, and NULLs it out +void SafeCloseHandle(__inout HANDLE * pHandle); + +////////////////////////////////////////////////////////////////////////////////////////////// + +#endif // __TABINC_H_ + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/TabletPCVer.h b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/TabletPCVer.h new file mode 100644 index 00000000000..1da7870bab8 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/TabletPCVer.h @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +////////////////////////////////////////////////////////////////////////////////////////////// +// +// This files must be include inside all RC files prior to including "common.ver" +// +////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef VER_FILEDESCRIPTION_STR +#define VER_FILEDESCRIPTION_STR "Microsoft Tablet PC Component" +#endif + +#ifndef VER_LEGALCOPYRIGHT_STR +#define VER_LEGALCOPYRIGHT_STR "Copyright \251 Microsoft Corp." +#endif + +#include +#include +#include + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/peninc.h b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/peninc.h new file mode 100644 index 00000000000..c9ce0f79968 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/peninc.h @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +#ifndef __PENINC_H_ +#define __PENINC_H_ + +#define STRSAFE_NO_DEPRECATE +#include +#include + +/////////////////////////////////////////////////////////////////////////////// + +#define MIN_SPACE64_X 0 +#define MIN_SPACE64_Y 0 +#define MAX_SPACE64_X 65535 +#define MAX_SPACE64_Y 65535 + +/////////////////////////////////////////////////////////////////////////////// + +typedef unsigned (__stdcall *PTHREAD_START) (void *); + +#define chBEGINTHREADEX(lpsa, cbStack, lpStartAddr, \ + lpvThreadParm, fdwCreate, lpIDThread) \ + ((HANDLE)_beginthreadex( \ + (void *) (lpsa), \ + (unsigned) (cbStack), \ + (PTHREAD_START) (lpStartAddr), \ + (void *) (lpvThreadParm), \ + (unsigned) (fdwCreate), \ + (unsigned *) (lpIDThread))) + +/////////////////////////////////////////////////////////////////////////////// + +#define MICROSOFT_TABLETPENSERVICE_PROPERTY _T("MicrosoftTabletPenServiceProperty") + +#define WISPTIS_PRESS_AND_HOLD_DISABLE_MASK 0x01 +#define WISPTIS_SYSTEM_GESTURE_WM_DISABLE_MASK 0x02 +#define WISPTIS_FLICK_LEARNING_MODE_MASK 0x04 + +#define PENPROCESS_COMMANDLINE _T("/ProcessActivate:%p;%p; /ProcessDeActivate:%p;%p; /EndSessionInfo:%p;%p;") + +#define PENPROCESS_ACTIVATEINFO _T("/ProcessActivate:") +#define PENPROCESS_DEACTIVATEINFO _T("/ProcessDeActivate:") +#define PENPROCESS_ENDSESSIONINFO _T("/EndSessionInfo:") + +#define PENPROCESS_PATH _T("\\SYSTEM32\\WISPTIS.EXE") + +#define WISPTIS_WITHNOINTEGRATEDDEVICE _T("/EndSessionInfo:%p;%p;") +#define WISPTIS_ENDSESSIONINFO _T("/EndSessionInfo:") + +#define WISPTIS_DEBUGGING _T("/Debugging") +#define WISPTIS_DEBUGGING _T("/Debugging") + +///////////////////////////////////////////////////////////////////////////// +// +// HR etc helpers +// + +#define DHR \ + HRESULT hr = S_OK; + +#define RHR \ + return hr; + +#define CHR(hr_op) \ + { \ + hr = hr_op; \ + if (FAILED(hr)) \ + goto CLEANUP; \ + } + +#define CHR_VERIFY(hr_op) \ + { \ + CHR(hr_op); \ + ASSERT (SUCCEEDED(hr)); \ + } + +#define CHR_MEMALLOC(pv_op) \ + { \ + CHR((pv_op) != NULL ? S_OK : E_OUTOFMEMORY); \ + } + +#define CHR_WIN32(bool_or_handle_op) \ + { \ + CHR((bool_or_handle_op) ? \ + S_OK : \ + HRESULT_FROM_WIN32(GetLastError())); \ + } + +// Shared by Wisptis and PenImc +#define WISPTIS_SM_MORE_DATA_EVENT_NAME _T("wisptis-1-%d-%u") +#define WISPTIS_SM_MUTEX_NAME _T("wisptis-2-%d-%u") +#define WISPTIS_SM_SECTION_NAME _T("wisptis-3-%d-%u") +#define WISPTIS_SM_THREAD_EVENT_NAME _T("wisptis-4-%u") + +#endif // __PENINC_H_ + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/pentypes.h b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/pentypes.h new file mode 100644 index 00000000000..7bf7e65104c --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/pentypes.h @@ -0,0 +1,214 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0498 */ +/* Compiler settings for pentypes.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + + +#ifndef __pentypes_h__ +#define __pentypes_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_pentypes_0000_0000 */ +/* [local] */ + +#include "tpcshrd.h" +#define TCXO_MARGIN 0x00000001 +#define TCXO_PREHOOK 0x00000002 +#define TCXO_CURSOR_STATE 0x00000004 +#define TCXO_NO_CURSOR_DOWN 0x00000008 +#define TCXO_NON_INTEGRATED 0x00000010 +#define TCXO_POSTHOOK 0x00000020 +#define TCXO_DONT_SHOW_CURSOR 0x00000080 +#define TCXO_DONT_VALIDATE_TCS 0x00000100 +#define TCXO_REPORT_RECT_MAPPING_CHANGE 0x00000200 +#define TCXO_ALLOW_FLICKS 0x00000400 +#define TCXO_ALLOW_FEEDBACK_TAPS 0x00000800 +#define TCXO_ALLOW_FEEDBACK_BARREL 0x00001000 +#define TCXO_ALLOW_ALL_TOUCH 0x00002000 +#define TCXO_ALL (TCXO_MARGIN | TCXO_PREHOOK | TCXO_CURSOR_STATE | TCXO_NO_CURSOR_DOWN | TCXO_NON_INTEGRATED | TCXO_POSTHOOK | TCXO_DONT_SHOW_CURSOR | TCXO_DONT_VALIDATE_TCS | TCXO_REPORT_RECT_MAPPING_CHANGE | TCXO_ALLOW_FLICKS | TCXO_ALLOW_FEEDBACK_TAPS | TCXO_ALLOW_FEEDBACK_BARREL | TCXO_ALLOW_ALL_TOUCH) +#define TCXO_HOOK (TCXO_PREHOOK | TCXO_POSTHOOK) +#define TCXS_DISABLED 0x00000001 +#define THWC_INTEGRATED 0x00000001 +#define THWC_CSR_MUST_TOUCH 0x00000002 +#define THWC_HARD_PROXIMITY 0x00000004 +#define THWC_PHYSID_CSRS 0x00000008 +#define IP_CURSOR_DOWN 0x00000001 +#define IP_INVERTED 0x00000002 +#define IP_MARGIN 0x00000004 +#define IP_BARREL_DOWN 0x00000008 +#define IP_RECT_MAPPING_CHANGED 0x00000010 +#define IP_ALL_STATUS_BITS (IP_CURSOR_DOWN | IP_INVERTED | IP_MARGIN | IP_BARREL_DOWN | IP_RECT_MAPPING_CHANGED) +#define TAB_SETTING_LINEARIZATION 0x00000001 +#define TAB_SETTING_PORTRAIT_USERTILT 0x00000002 +#define TAB_SETTING_LANDSCAPE_USERTILT 0x00000004 +#define TAB_SETTING_DISPLAY_ORIENTATION_DEFAULT_USERTILT 0x00000008 +#define TAB_SETTING_DISPLAY_ORIENTATION_90_USERTILT 0x00000010 +#define TAB_SETTING_DISPLAY_ORIENTATION_180_USERTILT 0x00000100 +#define TAB_SETTING_DISPLAY_ORIENTATION_270_USERTILT 0x00001000 +#define SE_TAP 0x00000010 +#define SE_DBL_TAP 0x00000011 +#define SE_RIGHT_TAP 0x00000012 +#define SE_DRAG 0x00000013 +#define SE_RIGHT_DRAG 0x00000014 +#define SE_HOLD_ENTER 0x00000015 +#define SE_HOLD_LEAVE 0x00000016 +#define SE_HOVER_ENTER 0x00000017 +#define SE_HOVER_LEAVE 0x00000018 +#define SE_MIDDLE_CLICK 0x00000019 +#define SE_KEY 0x0000001A +#define SE_MODIFIER_KEY 0x0000001B +#define SE_GESTURE_MODE 0x0000001C +#define SE_CURSOR 0x0000001D +#define SE_FLICK 0x0000001F +#define SE_MODIFIER_CTRL 0x00000001 +#define SE_MODIFIER_ALT 0x00000002 +#define SE_MODIFIER_SHIFT 0x00000004 +#define SE_NORMAL_CURSOR 0x00000001 +#define SE_ERASER_CURSOR 0x00000002 +#define SE_SYSTEMEVENT 0x00000001 +#define SE_TYPE_MOUSE 0x00000000 +#define SE_TYPE_KEYBOARD 0x00000001 +#define SE_DELAY_PACKET 0x0000000F +#define SE_PRE_TAPDRAG 0x0000001E +#define WM_TABLET_DEFBASE 0x02C0 +#define WM_TABLET_MAXOFFSET 0x20 +#define WM_TABLET_CONTEXTCREATE (WM_TABLET_DEFBASE + 0) +#define WM_TABLET_CONTEXTDESTROY (WM_TABLET_DEFBASE + 1) +#define WM_TABLET_CURSORNEW (WM_TABLET_DEFBASE + 2) +#define WM_TABLET_CURSORINRANGE (WM_TABLET_DEFBASE + 3) +#define WM_TABLET_CURSOROUTOFRANGE (WM_TABLET_DEFBASE + 4) +#define WM_TABLET_CURSORDOWN (WM_TABLET_DEFBASE + 5) +#define WM_TABLET_CURSORUP (WM_TABLET_DEFBASE + 6) +#define WM_TABLET_PACKET (WM_TABLET_DEFBASE + 7) +#define WM_TABLET_ADDED (WM_TABLET_DEFBASE + 8) +#define WM_TABLET_DELETED (WM_TABLET_DEFBASE + 9) +#define WM_TABLET_SYSTEMEVENT (WM_TABLET_DEFBASE + 10) +#define WM_TABLET_MAX (WM_TABLET_DEFBASE + WM_TABLET_MAXOFFSET) +#define TABLET_MESSAGE_EXTRA_INFO_MASK_PEN_OR_TOUCH 0xFF515700 +#define TABLET_MESSAGE_EXTRA_INFO_MASK_TOUCH 0xFF515780 +#define TABLET_MESSAGE_EXTRA_INFO_MASK_TIP 0xFF575100 +#define MICROSOFT_TABLETPENSERVICE_PROPERTY _T("MicrosoftTabletPenServiceProperty") +#define TABLET_DISABLE_PRESSANDHOLD 0x00000001 +#define TABLET_DISABLE_PENTAPFEEDBACK 0x00000008 +#define TABLET_DISABLE_PENBARRELFEEDBACK 0x00000010 +#define TABLET_DISABLE_TOUCHUIFORCEON 0x00000100 +#define TABLET_DISABLE_TOUCHUIFORCEOFF 0x00000200 +#define TABLET_DISABLE_TOUCHSWITCH 0x00008000 +#define TABLET_DISABLE_FLICKS 0x00010000 +#define TABLET_ENABLE_FLICKSONCONTEXT 0x00020000 +#define TABLET_ENABLE_FLICKLEARNINGMODE 0x00040000 +#define TABLET_DISABLE_SMOOTHSCROLLING 0x00080000 +#define WISP_WINTAB_ERROR MAKE_HRESULT(1, FACILITY_ITF, 0x201) +#define WISP_PACKET_BUFFER_TOO_SMALL MAKE_HRESULT(1, FACILITY_ITF, 0x211) +#define WISP_NO_DEFAULT_TABLET MAKE_HRESULT(1, FACILITY_ITF, 0x212) +#define WISP_TABLET_CONTEXT_NOT_FOUND MAKE_HRESULT(1, FACILITY_ITF, 0x213) +#define WISP_CURSOR_NOT_FOUND MAKE_HRESULT(1, FACILITY_ITF, 0x214) +#define WISP_INVALID_TABLET_INDEX MAKE_HRESULT(1, FACILITY_ITF, 0x215) +#define WISP_INVALID_TABLET_CONTEXT_INDEX MAKE_HRESULT(1, FACILITY_ITF, 0x216) +#define WISP_INVALID_CURSOR_INDEX MAKE_HRESULT(1, FACILITY_ITF, 0x217) +#define WISP_INVALID_BUTTON_INDEX MAKE_HRESULT(1, FACILITY_ITF, 0x218) +#define WISP_INVALID_PACKET_SERIAL_NUM MAKE_HRESULT(1, FACILITY_ITF, 0x219) +#define WISP_INVALID_WINDOW_HANDLE MAKE_HRESULT(1, FACILITY_ITF, 0x21a) +#define WISP_INVALID_INPUT_RECT MAKE_HRESULT(1, FACILITY_ITF, 0x21b) +#define WISP_INVALID_TABLET_CONTEXT_SETTINGS MAKE_HRESULT(1, FACILITY_ITF, 0x21c) +#define WISP_UNKNOWN_PROPERTY MAKE_HRESULT(1, FACILITY_ITF, 0x21d) +#define WISP_UNITS_CONVERSION_UNDEFINED MAKE_HRESULT(1, FACILITY_ITF, 0x21e) +#define SZ_REGKEY_PERSIST TEXT("Software\\Microsoft\\Wisp\\Pen\\Persist") +#define SZ_REGVAL_TYPE TEXT("type") +#define SZ_REGVAL_WINTABDEVICEID TEXT("WintabDeviceId") +#define SZ_REGVAL_HIDDEVICEPATH TEXT("HidDevicePath") +#define SZ_REGVAL_WINTABCURSORTYPE TEXT("WintabCursorType") +#define SZ_REGVAL_WINTABCURSORPHYSID TEXT("WintabCursorPhysid") +#define SZ_REGVAL_HIDCURSORID TEXT("HidCursorId") +#define SZ_REGVAL_HIDDEVICE TEXT("HidDevice") +#define SZ_REGVAL_NAME TEXT("Name") +typedef +enum _CONTEXT_ENABLE_TYPE + { CONTEXT_ENABLE = 1, + CONTEXT_DISABLE = 2 + } CONTEXT_ENABLE_TYPE; + +typedef enum _CONTEXT_ENABLE_TYPE *PCONTEXT_ENABLE_TYPE; + +typedef struct _TABLET_CONTEXT_SETTINGS + { + ULONG cPktProps; + GUID *pguidPktProps; + ULONG cPktBtns; + GUID *pguidPktBtns; + DWORD *pdwBtnDnMask; + DWORD *pdwBtnUpMask; + LONG lXMargin; + LONG lYMargin; + } TABLET_CONTEXT_SETTINGS; + +typedef /* [unique] */ __RPC_unique_pointer TABLET_CONTEXT_SETTINGS *PTABLET_CONTEXT_SETTINGS; + +#define SZ_EVENT_TABLETHARDWAREPRESENT TEXT("Global\\TabletHardwarePresent") + + +extern RPC_IF_HANDLE __MIDL_itf_pentypes_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_pentypes_0000_0000_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/tpcpen.h b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/tpcpen.h new file mode 100644 index 00000000000..8ed0083c55f --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/tpcpen.h @@ -0,0 +1,1809 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0498 */ +/* Compiler settings for tpcpen.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __tpcpen_h__ +#define __tpcpen_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ITabletEventSink_FWD_DEFINED__ +#define __ITabletEventSink_FWD_DEFINED__ +typedef interface ITabletEventSink ITabletEventSink; +#endif /* __ITabletEventSink_FWD_DEFINED__ */ + + +#ifndef __AsyncITabletEventSink_FWD_DEFINED__ +#define __AsyncITabletEventSink_FWD_DEFINED__ +typedef interface AsyncITabletEventSink AsyncITabletEventSink; +#endif /* __AsyncITabletEventSink_FWD_DEFINED__ */ + + +#ifndef __ITabletManager_FWD_DEFINED__ +#define __ITabletManager_FWD_DEFINED__ +typedef interface ITabletManager ITabletManager; +#endif /* __ITabletManager_FWD_DEFINED__ */ + + +#ifndef __ITablet_FWD_DEFINED__ +#define __ITablet_FWD_DEFINED__ +typedef interface ITablet ITablet; +#endif /* __ITablet_FWD_DEFINED__ */ + + +#ifndef __ITablet2_FWD_DEFINED__ +#define __ITablet2_FWD_DEFINED__ +typedef interface ITablet2 ITablet2; +#endif /* __ITablet2_FWD_DEFINED__ */ + + +#ifndef __ITabletSettings_FWD_DEFINED__ +#define __ITabletSettings_FWD_DEFINED__ +typedef interface ITabletSettings ITabletSettings; +#endif /* __ITabletSettings_FWD_DEFINED__ */ + + +#ifndef __ITabletContext_FWD_DEFINED__ +#define __ITabletContext_FWD_DEFINED__ +typedef interface ITabletContext ITabletContext; +#endif /* __ITabletContext_FWD_DEFINED__ */ + + +#ifndef __ITabletCursor_FWD_DEFINED__ +#define __ITabletCursor_FWD_DEFINED__ +typedef interface ITabletCursor ITabletCursor; +#endif /* __ITabletCursor_FWD_DEFINED__ */ + + +#ifndef __ITabletCursorButton_FWD_DEFINED__ +#define __ITabletCursorButton_FWD_DEFINED__ +typedef interface ITabletCursorButton ITabletCursorButton; +#endif /* __ITabletCursorButton_FWD_DEFINED__ */ + + +#ifndef __ITabletEventSink_FWD_DEFINED__ +#define __ITabletEventSink_FWD_DEFINED__ +typedef interface ITabletEventSink ITabletEventSink; +#endif /* __ITabletEventSink_FWD_DEFINED__ */ + + +#ifndef __ITabletManager_FWD_DEFINED__ +#define __ITabletManager_FWD_DEFINED__ +typedef interface ITabletManager ITabletManager; +#endif /* __ITabletManager_FWD_DEFINED__ */ + + +#ifndef __ITablet_FWD_DEFINED__ +#define __ITablet_FWD_DEFINED__ +typedef interface ITablet ITablet; +#endif /* __ITablet_FWD_DEFINED__ */ + + +#ifndef __ITabletContext_FWD_DEFINED__ +#define __ITabletContext_FWD_DEFINED__ +typedef interface ITabletContext ITabletContext; +#endif /* __ITabletContext_FWD_DEFINED__ */ + + +#ifndef __ITabletCursor_FWD_DEFINED__ +#define __ITabletCursor_FWD_DEFINED__ +typedef interface ITabletCursor ITabletCursor; +#endif /* __ITabletCursor_FWD_DEFINED__ */ + + +#ifndef __ITabletCursorButton_FWD_DEFINED__ +#define __ITabletCursorButton_FWD_DEFINED__ +typedef interface ITabletCursorButton ITabletCursorButton; +#endif /* __ITabletCursorButton_FWD_DEFINED__ */ + + +#ifndef __TabletManager_FWD_DEFINED__ +#define __TabletManager_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class TabletManager TabletManager; +#else +typedef struct TabletManager TabletManager; +#endif /* __cplusplus */ + +#endif /* __TabletManager_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "tpcshrd.h" +#include "pentypes.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_tpcpen_0000_0000 */ +/* [local] */ + + +#pragma once + + + + + + + +extern RPC_IF_HANDLE __MIDL_itf_tpcpen_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_tpcpen_0000_0000_v0_0_s_ifspec; + +#ifndef __ITabletEventSink_INTERFACE_DEFINED__ +#define __ITabletEventSink_INTERFACE_DEFINED__ + +/* interface ITabletEventSink */ +/* [unique][helpstring][async_uuid][uuid][object] */ + +typedef /* [unique] */ __RPC_unique_pointer ITabletEventSink *PTABLETEVENTSINK; + + +EXTERN_C const IID IID_ITabletEventSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("788459C8-26C8-4666-BF57-04AD3A0A5EB5") + ITabletEventSink : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ContextCreate( + /* [in] */ TABLET_CONTEXT_ID tcid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ContextDestroy( + /* [in] */ TABLET_CONTEXT_ID tcid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CursorNew( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CursorInRange( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CursorOutOfRange( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CursorDown( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ ULONG nSerialNumber, + /* [in] */ ULONG cbPkt, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkt) BYTE *pbPkt) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CursorUp( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ ULONG nSerialNumber, + /* [in] */ ULONG cbPkt, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkt) BYTE *pbPkt) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Packets( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ ULONG cPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts, + /* [size_is][unique][in] */ __RPC__in_ecount_full_opt(cPkts) ULONG *pnSerialNumbers, + /* [in] */ CURSOR_ID cid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SystemEvent( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ SYSTEM_EVENT event, + /* [in] */ SYSTEM_EVENT_DATA eventdata) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletEventSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletEventSink * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletEventSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletEventSink * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ContextCreate )( + ITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ContextDestroy )( + ITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *CursorNew )( + ITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *CursorInRange )( + ITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *CursorOutOfRange )( + ITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *CursorDown )( + ITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ ULONG nSerialNumber, + /* [in] */ ULONG cbPkt, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkt) BYTE *pbPkt); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *CursorUp )( + ITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ ULONG nSerialNumber, + /* [in] */ ULONG cbPkt, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkt) BYTE *pbPkt); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Packets )( + ITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ ULONG cPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts, + /* [size_is][unique][in] */ __RPC__in_ecount_full_opt(cPkts) ULONG *pnSerialNumbers, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SystemEvent )( + ITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ SYSTEM_EVENT event, + /* [in] */ SYSTEM_EVENT_DATA eventdata); + + END_INTERFACE + } ITabletEventSinkVtbl; + + interface ITabletEventSink + { + CONST_VTBL struct ITabletEventSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletEventSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletEventSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletEventSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletEventSink_ContextCreate(This,tcid) \ + ( (This)->lpVtbl -> ContextCreate(This,tcid) ) + +#define ITabletEventSink_ContextDestroy(This,tcid) \ + ( (This)->lpVtbl -> ContextDestroy(This,tcid) ) + +#define ITabletEventSink_CursorNew(This,tcid,cid) \ + ( (This)->lpVtbl -> CursorNew(This,tcid,cid) ) + +#define ITabletEventSink_CursorInRange(This,tcid,cid) \ + ( (This)->lpVtbl -> CursorInRange(This,tcid,cid) ) + +#define ITabletEventSink_CursorOutOfRange(This,tcid,cid) \ + ( (This)->lpVtbl -> CursorOutOfRange(This,tcid,cid) ) + +#define ITabletEventSink_CursorDown(This,tcid,cid,nSerialNumber,cbPkt,pbPkt) \ + ( (This)->lpVtbl -> CursorDown(This,tcid,cid,nSerialNumber,cbPkt,pbPkt) ) + +#define ITabletEventSink_CursorUp(This,tcid,cid,nSerialNumber,cbPkt,pbPkt) \ + ( (This)->lpVtbl -> CursorUp(This,tcid,cid,nSerialNumber,cbPkt,pbPkt) ) + +#define ITabletEventSink_Packets(This,tcid,cPkts,cbPkts,pbPkts,pnSerialNumbers,cid) \ + ( (This)->lpVtbl -> Packets(This,tcid,cPkts,cbPkts,pbPkts,pnSerialNumbers,cid) ) + +#define ITabletEventSink_SystemEvent(This,tcid,cid,event,eventdata) \ + ( (This)->lpVtbl -> SystemEvent(This,tcid,cid,event,eventdata) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletEventSink_INTERFACE_DEFINED__ */ + + +#ifndef __AsyncITabletEventSink_INTERFACE_DEFINED__ +#define __AsyncITabletEventSink_INTERFACE_DEFINED__ + +/* interface AsyncITabletEventSink */ +/* [uuid][unique][helpstring][object] */ + + +EXTERN_C const IID IID_AsyncITabletEventSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("CDF7D7D6-2E5D-47c7-90FC-C638C7FA3FC4") + AsyncITabletEventSink : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Begin_ContextCreate( + /* [in] */ TABLET_CONTEXT_ID tcid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Finish_ContextCreate( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Begin_ContextDestroy( + /* [in] */ TABLET_CONTEXT_ID tcid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Finish_ContextDestroy( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Begin_CursorNew( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Finish_CursorNew( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Begin_CursorInRange( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Finish_CursorInRange( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Begin_CursorOutOfRange( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Finish_CursorOutOfRange( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Begin_CursorDown( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ ULONG nSerialNumber, + /* [in] */ ULONG cbPkt, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkt) BYTE *pbPkt) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Finish_CursorDown( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Begin_CursorUp( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ ULONG nSerialNumber, + /* [in] */ ULONG cbPkt, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkt) BYTE *pbPkt) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Finish_CursorUp( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Begin_Packets( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ ULONG cPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts, + /* [size_is][unique][in] */ __RPC__in_ecount_full_opt(cPkts) ULONG *pnSerialNumbers, + /* [in] */ CURSOR_ID cid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Finish_Packets( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Begin_SystemEvent( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ SYSTEM_EVENT event, + /* [in] */ SYSTEM_EVENT_DATA eventdata) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Finish_SystemEvent( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct AsyncITabletEventSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + AsyncITabletEventSink * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + AsyncITabletEventSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + AsyncITabletEventSink * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Begin_ContextCreate )( + AsyncITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Finish_ContextCreate )( + AsyncITabletEventSink * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Begin_ContextDestroy )( + AsyncITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Finish_ContextDestroy )( + AsyncITabletEventSink * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Begin_CursorNew )( + AsyncITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Finish_CursorNew )( + AsyncITabletEventSink * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Begin_CursorInRange )( + AsyncITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Finish_CursorInRange )( + AsyncITabletEventSink * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Begin_CursorOutOfRange )( + AsyncITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Finish_CursorOutOfRange )( + AsyncITabletEventSink * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Begin_CursorDown )( + AsyncITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ ULONG nSerialNumber, + /* [in] */ ULONG cbPkt, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkt) BYTE *pbPkt); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Finish_CursorDown )( + AsyncITabletEventSink * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Begin_CursorUp )( + AsyncITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ ULONG nSerialNumber, + /* [in] */ ULONG cbPkt, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkt) BYTE *pbPkt); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Finish_CursorUp )( + AsyncITabletEventSink * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Begin_Packets )( + AsyncITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ ULONG cPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts, + /* [size_is][unique][in] */ __RPC__in_ecount_full_opt(cPkts) ULONG *pnSerialNumbers, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Finish_Packets )( + AsyncITabletEventSink * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Begin_SystemEvent )( + AsyncITabletEventSink * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [in] */ CURSOR_ID cid, + /* [in] */ SYSTEM_EVENT event, + /* [in] */ SYSTEM_EVENT_DATA eventdata); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Finish_SystemEvent )( + AsyncITabletEventSink * This); + + END_INTERFACE + } AsyncITabletEventSinkVtbl; + + interface AsyncITabletEventSink + { + CONST_VTBL struct AsyncITabletEventSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define AsyncITabletEventSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define AsyncITabletEventSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define AsyncITabletEventSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define AsyncITabletEventSink_Begin_ContextCreate(This,tcid) \ + ( (This)->lpVtbl -> Begin_ContextCreate(This,tcid) ) + +#define AsyncITabletEventSink_Finish_ContextCreate(This) \ + ( (This)->lpVtbl -> Finish_ContextCreate(This) ) + +#define AsyncITabletEventSink_Begin_ContextDestroy(This,tcid) \ + ( (This)->lpVtbl -> Begin_ContextDestroy(This,tcid) ) + +#define AsyncITabletEventSink_Finish_ContextDestroy(This) \ + ( (This)->lpVtbl -> Finish_ContextDestroy(This) ) + +#define AsyncITabletEventSink_Begin_CursorNew(This,tcid,cid) \ + ( (This)->lpVtbl -> Begin_CursorNew(This,tcid,cid) ) + +#define AsyncITabletEventSink_Finish_CursorNew(This) \ + ( (This)->lpVtbl -> Finish_CursorNew(This) ) + +#define AsyncITabletEventSink_Begin_CursorInRange(This,tcid,cid) \ + ( (This)->lpVtbl -> Begin_CursorInRange(This,tcid,cid) ) + +#define AsyncITabletEventSink_Finish_CursorInRange(This) \ + ( (This)->lpVtbl -> Finish_CursorInRange(This) ) + +#define AsyncITabletEventSink_Begin_CursorOutOfRange(This,tcid,cid) \ + ( (This)->lpVtbl -> Begin_CursorOutOfRange(This,tcid,cid) ) + +#define AsyncITabletEventSink_Finish_CursorOutOfRange(This) \ + ( (This)->lpVtbl -> Finish_CursorOutOfRange(This) ) + +#define AsyncITabletEventSink_Begin_CursorDown(This,tcid,cid,nSerialNumber,cbPkt,pbPkt) \ + ( (This)->lpVtbl -> Begin_CursorDown(This,tcid,cid,nSerialNumber,cbPkt,pbPkt) ) + +#define AsyncITabletEventSink_Finish_CursorDown(This) \ + ( (This)->lpVtbl -> Finish_CursorDown(This) ) + +#define AsyncITabletEventSink_Begin_CursorUp(This,tcid,cid,nSerialNumber,cbPkt,pbPkt) \ + ( (This)->lpVtbl -> Begin_CursorUp(This,tcid,cid,nSerialNumber,cbPkt,pbPkt) ) + +#define AsyncITabletEventSink_Finish_CursorUp(This) \ + ( (This)->lpVtbl -> Finish_CursorUp(This) ) + +#define AsyncITabletEventSink_Begin_Packets(This,tcid,cPkts,cbPkts,pbPkts,pnSerialNumbers,cid) \ + ( (This)->lpVtbl -> Begin_Packets(This,tcid,cPkts,cbPkts,pbPkts,pnSerialNumbers,cid) ) + +#define AsyncITabletEventSink_Finish_Packets(This) \ + ( (This)->lpVtbl -> Finish_Packets(This) ) + +#define AsyncITabletEventSink_Begin_SystemEvent(This,tcid,cid,event,eventdata) \ + ( (This)->lpVtbl -> Begin_SystemEvent(This,tcid,cid,event,eventdata) ) + +#define AsyncITabletEventSink_Finish_SystemEvent(This) \ + ( (This)->lpVtbl -> Finish_SystemEvent(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __AsyncITabletEventSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletManager_INTERFACE_DEFINED__ +#define __ITabletManager_INTERFACE_DEFINED__ + +/* interface ITabletManager */ +/* [unique][helpstring][uuid][object] */ + +typedef /* [unique] */ __RPC_unique_pointer ITabletManager *PTABLETMANAGER; + + +EXTERN_C const IID IID_ITabletManager; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("764DE8AA-1867-47C1-8F6A-122445ABD89A") + ITabletManager : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDefaultTablet( + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetTabletCount( + /* [out] */ __RPC__out ULONG *pcTablets) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetTablet( + /* [in] */ ULONG iTablet, + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetTabletContextById( + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [out] */ __RPC__deref_out_opt ITabletContext **ppContext) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetCursorById( + /* [in] */ CURSOR_ID cid, + /* [out] */ __RPC__deref_out_opt ITabletCursor **ppCursor) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletManagerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletManager * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletManager * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletManager * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDefaultTablet )( + ITabletManager * This, + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTabletCount )( + ITabletManager * This, + /* [out] */ __RPC__out ULONG *pcTablets); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTablet )( + ITabletManager * This, + /* [in] */ ULONG iTablet, + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTabletContextById )( + ITabletManager * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [out] */ __RPC__deref_out_opt ITabletContext **ppContext); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCursorById )( + ITabletManager * This, + /* [in] */ CURSOR_ID cid, + /* [out] */ __RPC__deref_out_opt ITabletCursor **ppCursor); + + END_INTERFACE + } ITabletManagerVtbl; + + interface ITabletManager + { + CONST_VTBL struct ITabletManagerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletManager_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletManager_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletManager_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletManager_GetDefaultTablet(This,ppTablet) \ + ( (This)->lpVtbl -> GetDefaultTablet(This,ppTablet) ) + +#define ITabletManager_GetTabletCount(This,pcTablets) \ + ( (This)->lpVtbl -> GetTabletCount(This,pcTablets) ) + +#define ITabletManager_GetTablet(This,iTablet,ppTablet) \ + ( (This)->lpVtbl -> GetTablet(This,iTablet,ppTablet) ) + +#define ITabletManager_GetTabletContextById(This,tcid,ppContext) \ + ( (This)->lpVtbl -> GetTabletContextById(This,tcid,ppContext) ) + +#define ITabletManager_GetCursorById(This,cid,ppCursor) \ + ( (This)->lpVtbl -> GetCursorById(This,cid,ppCursor) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletManager_INTERFACE_DEFINED__ */ + + +#ifndef __ITablet_INTERFACE_DEFINED__ +#define __ITablet_INTERFACE_DEFINED__ + +/* interface ITablet */ +/* [unique][helpstring][uuid][object] */ + +typedef /* [unique] */ __RPC_unique_pointer ITablet *PTABLET; + + +EXTERN_C const IID IID_ITablet; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("1CB2EFC3-ABC7-4172-8FCB-3BC9CB93E29F") + ITablet : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDefaultContextSettings( + /* [out] */ __RPC__deref_out_opt TABLET_CONTEXT_SETTINGS **ppTCS) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CreateContext( + /* [in] */ __RPC__in HWND hWnd, + /* [unique][in] */ __RPC__in_opt RECT *prcInput, + /* [in] */ DWORD dwOptions, + /* [unique][in] */ __RPC__in_opt TABLET_CONTEXT_SETTINGS *pTCS, + /* [in] */ CONTEXT_ENABLE_TYPE cet, + /* [out] */ __RPC__deref_out_opt ITabletContext **ppCtx, + /* [unique][out][in] */ __RPC__inout_opt TABLET_CONTEXT_ID *pTcid, + /* [unique][out][in] */ __RPC__deref_opt_inout_opt PACKET_DESCRIPTION **ppPD, + /* [unique][in] */ __RPC__in_opt ITabletEventSink *pSink) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetName( + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszName) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMaxInputRect( + /* [out] */ __RPC__out RECT *prcInput) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetHardwareCaps( + /* [out] */ __RPC__out DWORD *pdwCaps) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPropertyMetrics( + /* [in] */ __RPC__in REFGUID rguid, + /* [out] */ __RPC__out PROPERTY_METRICS *pPM) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPlugAndPlayId( + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszPPId) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetCursorCount( + /* [out] */ __RPC__out ULONG *pcCurs) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetCursor( + /* [in] */ ULONG iCur, + /* [out] */ __RPC__deref_out_opt ITabletCursor **ppCur) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITablet * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITablet * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITablet * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDefaultContextSettings )( + ITablet * This, + /* [out] */ __RPC__deref_out_opt TABLET_CONTEXT_SETTINGS **ppTCS); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *CreateContext )( + ITablet * This, + /* [in] */ __RPC__in HWND hWnd, + /* [unique][in] */ __RPC__in_opt RECT *prcInput, + /* [in] */ DWORD dwOptions, + /* [unique][in] */ __RPC__in_opt TABLET_CONTEXT_SETTINGS *pTCS, + /* [in] */ CONTEXT_ENABLE_TYPE cet, + /* [out] */ __RPC__deref_out_opt ITabletContext **ppCtx, + /* [unique][out][in] */ __RPC__inout_opt TABLET_CONTEXT_ID *pTcid, + /* [unique][out][in] */ __RPC__deref_opt_inout_opt PACKET_DESCRIPTION **ppPD, + /* [unique][in] */ __RPC__in_opt ITabletEventSink *pSink); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetName )( + ITablet * This, + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszName); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMaxInputRect )( + ITablet * This, + /* [out] */ __RPC__out RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetHardwareCaps )( + ITablet * This, + /* [out] */ __RPC__out DWORD *pdwCaps); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPropertyMetrics )( + ITablet * This, + /* [in] */ __RPC__in REFGUID rguid, + /* [out] */ __RPC__out PROPERTY_METRICS *pPM); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPlugAndPlayId )( + ITablet * This, + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszPPId); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCursorCount )( + ITablet * This, + /* [out] */ __RPC__out ULONG *pcCurs); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCursor )( + ITablet * This, + /* [in] */ ULONG iCur, + /* [out] */ __RPC__deref_out_opt ITabletCursor **ppCur); + + END_INTERFACE + } ITabletVtbl; + + interface ITablet + { + CONST_VTBL struct ITabletVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITablet_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITablet_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITablet_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITablet_GetDefaultContextSettings(This,ppTCS) \ + ( (This)->lpVtbl -> GetDefaultContextSettings(This,ppTCS) ) + +#define ITablet_CreateContext(This,hWnd,prcInput,dwOptions,pTCS,cet,ppCtx,pTcid,ppPD,pSink) \ + ( (This)->lpVtbl -> CreateContext(This,hWnd,prcInput,dwOptions,pTCS,cet,ppCtx,pTcid,ppPD,pSink) ) + +#define ITablet_GetName(This,ppwszName) \ + ( (This)->lpVtbl -> GetName(This,ppwszName) ) + +#define ITablet_GetMaxInputRect(This,prcInput) \ + ( (This)->lpVtbl -> GetMaxInputRect(This,prcInput) ) + +#define ITablet_GetHardwareCaps(This,pdwCaps) \ + ( (This)->lpVtbl -> GetHardwareCaps(This,pdwCaps) ) + +#define ITablet_GetPropertyMetrics(This,rguid,pPM) \ + ( (This)->lpVtbl -> GetPropertyMetrics(This,rguid,pPM) ) + +#define ITablet_GetPlugAndPlayId(This,ppwszPPId) \ + ( (This)->lpVtbl -> GetPlugAndPlayId(This,ppwszPPId) ) + +#define ITablet_GetCursorCount(This,pcCurs) \ + ( (This)->lpVtbl -> GetCursorCount(This,pcCurs) ) + +#define ITablet_GetCursor(This,iCur,ppCur) \ + ( (This)->lpVtbl -> GetCursor(This,iCur,ppCur) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITablet_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_tpcpen_0000_0003 */ +/* [local] */ + +typedef +enum _TABLET_DEVICE_KIND + { TABLET_DEVICE_MOUSE = 0, + TABLET_DEVICE_PEN = ( TABLET_DEVICE_MOUSE + 1 ) , + TABLET_DEVICE_TOUCH = ( TABLET_DEVICE_PEN + 1 ) + } TABLET_DEVICE_KIND; + + + +extern RPC_IF_HANDLE __MIDL_itf_tpcpen_0000_0003_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_tpcpen_0000_0003_v0_0_s_ifspec; + +#ifndef __ITablet2_INTERFACE_DEFINED__ +#define __ITablet2_INTERFACE_DEFINED__ + +/* interface ITablet2 */ +/* [unique][helpstring][uuid][object] */ + +typedef /* [unique] */ __RPC_unique_pointer ITablet2 *PTABLET2; + + +EXTERN_C const IID IID_ITablet2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C247F616-BBEB-406A-AED3-F75E656599AE") + ITablet2 : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDeviceKind( + /* [out] */ __RPC__out TABLET_DEVICE_KIND *pKind) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMatchingScreenRect( + /* [out] */ __RPC__out RECT *prcInput) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITablet2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITablet2 * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITablet2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITablet2 * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDeviceKind )( + ITablet2 * This, + /* [out] */ __RPC__out TABLET_DEVICE_KIND *pKind); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMatchingScreenRect )( + ITablet2 * This, + /* [out] */ __RPC__out RECT *prcInput); + + END_INTERFACE + } ITablet2Vtbl; + + interface ITablet2 + { + CONST_VTBL struct ITablet2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITablet2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITablet2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITablet2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITablet2_GetDeviceKind(This,pKind) \ + ( (This)->lpVtbl -> GetDeviceKind(This,pKind) ) + +#define ITablet2_GetMatchingScreenRect(This,prcInput) \ + ( (This)->lpVtbl -> GetMatchingScreenRect(This,prcInput) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITablet2_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletSettings_INTERFACE_DEFINED__ +#define __ITabletSettings_INTERFACE_DEFINED__ + +/* interface ITabletSettings */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletSettings *PTABLETSETTINGS; + + +EXTERN_C const IID IID_ITabletSettings; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("120ae7c9-36f7-4be6-93da-e5f266847b01") + ITabletSettings : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetProperty( + /* [in] */ DWORD dwProperty, + /* [out][in] */ __RPC__inout DWORD *pcbData, + /* [length_is][size_is][unique][out][in] */ __RPC__inout_ecount_part_opt(*pcbData, *pcbData) BYTE *pbData) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetProperty( + /* [in] */ DWORD dwProperty, + /* [in] */ DWORD cbData, + /* [size_is][unique][in] */ __RPC__in_ecount_full_opt(cbData) BYTE *pbData) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletSettingsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletSettings * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletSettings * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletSettings * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetProperty )( + ITabletSettings * This, + /* [in] */ DWORD dwProperty, + /* [out][in] */ __RPC__inout DWORD *pcbData, + /* [length_is][size_is][unique][out][in] */ __RPC__inout_ecount_part_opt(*pcbData, *pcbData) BYTE *pbData); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetProperty )( + ITabletSettings * This, + /* [in] */ DWORD dwProperty, + /* [in] */ DWORD cbData, + /* [size_is][unique][in] */ __RPC__in_ecount_full_opt(cbData) BYTE *pbData); + + END_INTERFACE + } ITabletSettingsVtbl; + + interface ITabletSettings + { + CONST_VTBL struct ITabletSettingsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletSettings_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletSettings_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletSettings_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletSettings_GetProperty(This,dwProperty,pcbData,pbData) \ + ( (This)->lpVtbl -> GetProperty(This,dwProperty,pcbData,pbData) ) + +#define ITabletSettings_SetProperty(This,dwProperty,cbData,pbData) \ + ( (This)->lpVtbl -> SetProperty(This,dwProperty,cbData,pbData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletSettings_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletContext_INTERFACE_DEFINED__ +#define __ITabletContext_INTERFACE_DEFINED__ + +/* interface ITabletContext */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletContext *PTABLETCONTEXT; + + +EXTERN_C const IID IID_ITabletContext; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("45AAAF04-9D6F-41AE-8ED1-ECD6D4B2F17F") + ITabletContext : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetId( + /* [out] */ __RPC__out TABLET_CONTEXT_ID *pTcid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetWindow( + /* [out] */ __RPC__deref_out_opt HWND *pHwnd) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetSettings( + /* [out] */ __RPC__deref_out_opt TABLET_CONTEXT_SETTINGS **ppTCS) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetTablet( + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Enable( + /* [in] */ CONTEXT_ENABLE_TYPE cet) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetOptions( + /* [out] */ __RPC__out DWORD *pdwOptions) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPacketDescription( + /* [out] */ __RPC__deref_out_opt PACKET_DESCRIPTION **ppPD) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStatus( + /* [out] */ __RPC__out DWORD *pdwStatus) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetInputRect( + /* [out] */ __RPC__out RECT *prcInput) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetInputRect( + /* [unique][in] */ __RPC__in_opt RECT *prcInput) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDevInputRect( + /* [unique][in] */ __RPC__in_opt RECT *prcInput) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDevInputRect( + /* [out] */ __RPC__out RECT *prcInput) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetCapture( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ReleaseCapture( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetCursorCapture( + /* [in] */ CURSOR_ID cid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ReleaseCursorCapture( + /* [in] */ CURSOR_ID cid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPackets( + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [out][in] */ __RPC__inout ULONG *pcPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][out] */ __RPC__out_ecount_full(cbPkts) BYTE *pbPkts, + /* [out] */ __RPC__out CURSOR_ID *pCid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE PeekPackets( + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [out][in] */ __RPC__inout ULONG *pcPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][out] */ __RPC__out_ecount_full(cbPkts) BYTE *pbPkts, + /* [out] */ __RPC__out CURSOR_ID *pCid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE FlushPackets( + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE FlushQueue( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPacketCount( + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [out] */ __RPC__out ULONG *pcPkts) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetPacketQueueInfo( + /* [out] */ __RPC__out ULONG *pnBegin, + /* [out] */ __RPC__out ULONG *pnEnd, + /* [out] */ __RPC__out ULONG *pcPkts) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ForwardPackets( + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE InjectPackets( + /* [in] */ ULONG cPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cPkts) CURSOR_ID *pCids) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ModifyPackets( + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ConvertToScreenCoordinates( + /* [in] */ ULONG cPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts, + /* [size_is][out] */ __RPC__out_ecount_full(cPkts) POINT *pPointsInScreen) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletContextVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletContext * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletContext * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletContext * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetId )( + ITabletContext * This, + /* [out] */ __RPC__out TABLET_CONTEXT_ID *pTcid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetWindow )( + ITabletContext * This, + /* [out] */ __RPC__deref_out_opt HWND *pHwnd); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetSettings )( + ITabletContext * This, + /* [out] */ __RPC__deref_out_opt TABLET_CONTEXT_SETTINGS **ppTCS); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTablet )( + ITabletContext * This, + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Enable )( + ITabletContext * This, + /* [in] */ CONTEXT_ENABLE_TYPE cet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetOptions )( + ITabletContext * This, + /* [out] */ __RPC__out DWORD *pdwOptions); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPacketDescription )( + ITabletContext * This, + /* [out] */ __RPC__deref_out_opt PACKET_DESCRIPTION **ppPD); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetStatus )( + ITabletContext * This, + /* [out] */ __RPC__out DWORD *pdwStatus); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetInputRect )( + ITabletContext * This, + /* [out] */ __RPC__out RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetInputRect )( + ITabletContext * This, + /* [unique][in] */ __RPC__in_opt RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetDevInputRect )( + ITabletContext * This, + /* [unique][in] */ __RPC__in_opt RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDevInputRect )( + ITabletContext * This, + /* [out] */ __RPC__out RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetCapture )( + ITabletContext * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ReleaseCapture )( + ITabletContext * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetCursorCapture )( + ITabletContext * This, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ReleaseCursorCapture )( + ITabletContext * This, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPackets )( + ITabletContext * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [out][in] */ __RPC__inout ULONG *pcPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][out] */ __RPC__out_ecount_full(cbPkts) BYTE *pbPkts, + /* [out] */ __RPC__out CURSOR_ID *pCid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *PeekPackets )( + ITabletContext * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [out][in] */ __RPC__inout ULONG *pcPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][out] */ __RPC__out_ecount_full(cbPkts) BYTE *pbPkts, + /* [out] */ __RPC__out CURSOR_ID *pCid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *FlushPackets )( + ITabletContext * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *FlushQueue )( + ITabletContext * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPacketCount )( + ITabletContext * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [out] */ __RPC__out ULONG *pcPkts); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPacketQueueInfo )( + ITabletContext * This, + /* [out] */ __RPC__out ULONG *pnBegin, + /* [out] */ __RPC__out ULONG *pnEnd, + /* [out] */ __RPC__out ULONG *pcPkts); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ForwardPackets )( + ITabletContext * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *InjectPackets )( + ITabletContext * This, + /* [in] */ ULONG cPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cPkts) CURSOR_ID *pCids); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ModifyPackets )( + ITabletContext * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ConvertToScreenCoordinates )( + ITabletContext * This, + /* [in] */ ULONG cPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts, + /* [size_is][out] */ __RPC__out_ecount_full(cPkts) POINT *pPointsInScreen); + + END_INTERFACE + } ITabletContextVtbl; + + interface ITabletContext + { + CONST_VTBL struct ITabletContextVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletContext_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletContext_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletContext_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletContext_GetId(This,pTcid) \ + ( (This)->lpVtbl -> GetId(This,pTcid) ) + +#define ITabletContext_GetWindow(This,pHwnd) \ + ( (This)->lpVtbl -> GetWindow(This,pHwnd) ) + +#define ITabletContext_GetSettings(This,ppTCS) \ + ( (This)->lpVtbl -> GetSettings(This,ppTCS) ) + +#define ITabletContext_GetTablet(This,ppTablet) \ + ( (This)->lpVtbl -> GetTablet(This,ppTablet) ) + +#define ITabletContext_Enable(This,cet) \ + ( (This)->lpVtbl -> Enable(This,cet) ) + +#define ITabletContext_GetOptions(This,pdwOptions) \ + ( (This)->lpVtbl -> GetOptions(This,pdwOptions) ) + +#define ITabletContext_GetPacketDescription(This,ppPD) \ + ( (This)->lpVtbl -> GetPacketDescription(This,ppPD) ) + +#define ITabletContext_GetStatus(This,pdwStatus) \ + ( (This)->lpVtbl -> GetStatus(This,pdwStatus) ) + +#define ITabletContext_GetInputRect(This,prcInput) \ + ( (This)->lpVtbl -> GetInputRect(This,prcInput) ) + +#define ITabletContext_SetInputRect(This,prcInput) \ + ( (This)->lpVtbl -> SetInputRect(This,prcInput) ) + +#define ITabletContext_SetDevInputRect(This,prcInput) \ + ( (This)->lpVtbl -> SetDevInputRect(This,prcInput) ) + +#define ITabletContext_GetDevInputRect(This,prcInput) \ + ( (This)->lpVtbl -> GetDevInputRect(This,prcInput) ) + +#define ITabletContext_SetCapture(This) \ + ( (This)->lpVtbl -> SetCapture(This) ) + +#define ITabletContext_ReleaseCapture(This) \ + ( (This)->lpVtbl -> ReleaseCapture(This) ) + +#define ITabletContext_SetCursorCapture(This,cid) \ + ( (This)->lpVtbl -> SetCursorCapture(This,cid) ) + +#define ITabletContext_ReleaseCursorCapture(This,cid) \ + ( (This)->lpVtbl -> ReleaseCursorCapture(This,cid) ) + +#define ITabletContext_GetPackets(This,nBegin,nEnd,pcPkts,cbPkts,pbPkts,pCid) \ + ( (This)->lpVtbl -> GetPackets(This,nBegin,nEnd,pcPkts,cbPkts,pbPkts,pCid) ) + +#define ITabletContext_PeekPackets(This,nBegin,nEnd,pcPkts,cbPkts,pbPkts,pCid) \ + ( (This)->lpVtbl -> PeekPackets(This,nBegin,nEnd,pcPkts,cbPkts,pbPkts,pCid) ) + +#define ITabletContext_FlushPackets(This,nBegin,nEnd) \ + ( (This)->lpVtbl -> FlushPackets(This,nBegin,nEnd) ) + +#define ITabletContext_FlushQueue(This) \ + ( (This)->lpVtbl -> FlushQueue(This) ) + +#define ITabletContext_GetPacketCount(This,nBegin,nEnd,pcPkts) \ + ( (This)->lpVtbl -> GetPacketCount(This,nBegin,nEnd,pcPkts) ) + +#define ITabletContext_GetPacketQueueInfo(This,pnBegin,pnEnd,pcPkts) \ + ( (This)->lpVtbl -> GetPacketQueueInfo(This,pnBegin,pnEnd,pcPkts) ) + +#define ITabletContext_ForwardPackets(This,nBegin,nEnd) \ + ( (This)->lpVtbl -> ForwardPackets(This,nBegin,nEnd) ) + +#define ITabletContext_InjectPackets(This,cPkts,cbPkts,pbPkts,pCids) \ + ( (This)->lpVtbl -> InjectPackets(This,cPkts,cbPkts,pbPkts,pCids) ) + +#define ITabletContext_ModifyPackets(This,nBegin,nEnd,cbPkts,pbPkts) \ + ( (This)->lpVtbl -> ModifyPackets(This,nBegin,nEnd,cbPkts,pbPkts) ) + +#define ITabletContext_ConvertToScreenCoordinates(This,cPkts,cbPkts,pbPkts,pPointsInScreen) \ + ( (This)->lpVtbl -> ConvertToScreenCoordinates(This,cPkts,cbPkts,pbPkts,pPointsInScreen) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletContext_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletCursor_INTERFACE_DEFINED__ +#define __ITabletCursor_INTERFACE_DEFINED__ + +/* interface ITabletCursor */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletCursor *PTABLETCURSOR; + + +EXTERN_C const IID IID_ITabletCursor; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("EF9953C6-B472-4B02-9D22-D0E247ADE0E8") + ITabletCursor : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetName( + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszName) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE IsInverted( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetId( + /* [out] */ __RPC__out CURSOR_ID *pCid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetTablet( + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetButtonCount( + /* [out] */ __RPC__out ULONG *pcButtons) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetButton( + /* [in] */ ULONG iButton, + /* [out] */ __RPC__deref_out_opt ITabletCursorButton **ppButton) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletCursorVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletCursor * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletCursor * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletCursor * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetName )( + ITabletCursor * This, + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszName); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *IsInverted )( + ITabletCursor * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetId )( + ITabletCursor * This, + /* [out] */ __RPC__out CURSOR_ID *pCid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTablet )( + ITabletCursor * This, + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetButtonCount )( + ITabletCursor * This, + /* [out] */ __RPC__out ULONG *pcButtons); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetButton )( + ITabletCursor * This, + /* [in] */ ULONG iButton, + /* [out] */ __RPC__deref_out_opt ITabletCursorButton **ppButton); + + END_INTERFACE + } ITabletCursorVtbl; + + interface ITabletCursor + { + CONST_VTBL struct ITabletCursorVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletCursor_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletCursor_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletCursor_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletCursor_GetName(This,ppwszName) \ + ( (This)->lpVtbl -> GetName(This,ppwszName) ) + +#define ITabletCursor_IsInverted(This) \ + ( (This)->lpVtbl -> IsInverted(This) ) + +#define ITabletCursor_GetId(This,pCid) \ + ( (This)->lpVtbl -> GetId(This,pCid) ) + +#define ITabletCursor_GetTablet(This,ppTablet) \ + ( (This)->lpVtbl -> GetTablet(This,ppTablet) ) + +#define ITabletCursor_GetButtonCount(This,pcButtons) \ + ( (This)->lpVtbl -> GetButtonCount(This,pcButtons) ) + +#define ITabletCursor_GetButton(This,iButton,ppButton) \ + ( (This)->lpVtbl -> GetButton(This,iButton,ppButton) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletCursor_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletCursorButton_INTERFACE_DEFINED__ +#define __ITabletCursorButton_INTERFACE_DEFINED__ + +/* interface ITabletCursorButton */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletCursorButton *PTABLETCURSORBUTTON; + + +EXTERN_C const IID IID_ITabletCursorButton; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("997A992E-8B6C-4945-BC17-A1EE563B3AB7") + ITabletCursorButton : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetName( + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszName) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetGuid( + /* [out] */ __RPC__out GUID *pguidBtn) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletCursorButtonVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletCursorButton * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletCursorButton * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletCursorButton * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetName )( + ITabletCursorButton * This, + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszName); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetGuid )( + ITabletCursorButton * This, + /* [out] */ __RPC__out GUID *pguidBtn); + + END_INTERFACE + } ITabletCursorButtonVtbl; + + interface ITabletCursorButton + { + CONST_VTBL struct ITabletCursorButtonVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletCursorButton_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletCursorButton_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletCursorButton_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletCursorButton_GetName(This,ppwszName) \ + ( (This)->lpVtbl -> GetName(This,ppwszName) ) + +#define ITabletCursorButton_GetGuid(This,pguidBtn) \ + ( (This)->lpVtbl -> GetGuid(This,pguidBtn) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletCursorButton_INTERFACE_DEFINED__ */ + + + +#ifndef __TABLETLib_LIBRARY_DEFINED__ +#define __TABLETLib_LIBRARY_DEFINED__ + +/* library TABLETLib */ +/* [helpstring][version][uuid] */ + + + + + + + + +EXTERN_C const IID LIBID_TABLETLib; + +EXTERN_C const CLSID CLSID_TabletManager; + +#ifdef __cplusplus + +class DECLSPEC_UUID("786CDB70-1628-44A0-853C-5D340A499137") +TabletManager; +#endif +#endif /* __TABLETLib_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +unsigned long __RPC_USER HWND_UserSize( unsigned long *, unsigned long , HWND * ); +unsigned char * __RPC_USER HWND_UserMarshal( unsigned long *, unsigned char *, HWND * ); +unsigned char * __RPC_USER HWND_UserUnmarshal(unsigned long *, unsigned char *, HWND * ); +void __RPC_USER HWND_UserFree( unsigned long *, HWND * ); + +unsigned long __RPC_USER HWND_UserSize64( unsigned long *, unsigned long , HWND * ); +unsigned char * __RPC_USER HWND_UserMarshal64( unsigned long *, unsigned char *, HWND * ); +unsigned char * __RPC_USER HWND_UserUnmarshal64(unsigned long *, unsigned char *, HWND * ); +void __RPC_USER HWND_UserFree64( unsigned long *, HWND * ); + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/tpcpen_i.c b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/tpcpen_i.c new file mode 100644 index 00000000000..b65145f11e7 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/tpcpen_i.c @@ -0,0 +1,113 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 7.00.0499 */ +/* Compiler settings for tpcpen.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, IID_ITabletEventSink,0x788459C8,0x26C8,0x4666,0xBF,0x57,0x04,0xAD,0x3A,0x0A,0x5E,0xB5); + + +MIDL_DEFINE_GUID(IID, IID_AsyncITabletEventSink,0xCDF7D7D6,0x2E5D,0x47c7,0x90,0xFC,0xC6,0x38,0xC7,0xFA,0x3F,0xC4); + + +MIDL_DEFINE_GUID(IID, IID_ITabletManager,0x764DE8AA,0x1867,0x47C1,0x8F,0x6A,0x12,0x24,0x45,0xAB,0xD8,0x9A); + + +MIDL_DEFINE_GUID(IID, IID_ITablet,0x1CB2EFC3,0xABC7,0x4172,0x8F,0xCB,0x3B,0xC9,0xCB,0x93,0xE2,0x9F); + + +MIDL_DEFINE_GUID(IID, IID_ITablet2,0xC247F616,0xBBEB,0x406A,0xAE,0xD3,0xF7,0x5E,0x65,0x65,0x99,0xAE); + + +MIDL_DEFINE_GUID(IID, IID_ITabletSettings,0x120ae7c9,0x36f7,0x4be6,0x93,0xda,0xe5,0xf2,0x66,0x84,0x7b,0x01); + + +MIDL_DEFINE_GUID(IID, IID_ITabletContext,0x45AAAF04,0x9D6F,0x41AE,0x8E,0xD1,0xEC,0xD6,0xD4,0xB2,0xF1,0x7F); + + +MIDL_DEFINE_GUID(IID, IID_ITabletCursor,0xEF9953C6,0xB472,0x4B02,0x9D,0x22,0xD0,0xE2,0x47,0xAD,0xE0,0xE8); + + +MIDL_DEFINE_GUID(IID, IID_ITabletCursorButton,0x997A992E,0x8B6C,0x4945,0xBC,0x17,0xA1,0xEE,0x56,0x3B,0x3A,0xB7); + + +MIDL_DEFINE_GUID(IID, LIBID_TABLETLib,0xC3F76406,0x6CA5,0x4BCD,0x85,0xE4,0x0E,0x7F,0x9E,0x05,0xD5,0x08); + + +MIDL_DEFINE_GUID(CLSID, CLSID_TabletManager,0x786CDB70,0x1628,0x44A0,0x85,0x3C,0x5D,0x34,0x0A,0x49,0x91,0x37); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/tpguuid.h b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/tpguuid.h new file mode 100644 index 00000000000..051fb8ea33c --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/tpguuid.h @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +#pragma once + +// None of the interfaces should change but... + +#define TABLETMANAGERP_INTERFACE uuid(663C73A5-8715-4499-B809-43689A93086B) +#define TABLETP_INTERFACE uuid(E65752FA-600B-43bd-8BFE-6A686FA3A201) +#define TABLETCONTEXTP_INTERFACE uuid(22F74D0A-694F-4f47-A5CE-AE08A6409AC8) +#define TABLETCURSORP_INTERFACE uuid(35DE0002-232C-4629-A915-7E600E80CD88) +#define TABLETCURSORBUTTONP_INTERFACE uuid(FCA502B0-5409-434d-8C35-A96C76CCA99C) +#define TABLETEVENTSINKP_INTERFACE uuid(287A9E67-8D1D-4a65-8DB4-51915395D019) +#define RECOPRIVATE_INTERFACE uuid(D3BD1CEE-2BAC-4114-94AF-D1541B032046) +#define RECOGNIZERPRIVATE_INTERFACE uuid(709AD3A5-7A2B-4edf-8939-D7BF6FF02327) +#define RECOMANAGER_INTERFACE uuid(C2E8F101-5D03-42EE-B90A-352557831039) +#define USERLEXICONMANAGER_INTERFACE uuid(1207B722-009D-495b-8C98-3A130F6DBE47) +#define ALTERNATE_INTERFACE uuid(A5055FC1-1A22-4F22-B306-76151BD53850) +#define RECOASYNCRESULTS_INTERFACE uuid(250CEF9C-121F-493d-ADCD-7A2A6823C0FD) +#define RECOCONTEXT_INTERFACE uuid(E6DAB875-75AF-4C8A-9665-2B6A44DD0F26) +#define RECOGNIZER_INTERFACE uuid(3A182AD6-596A-4070-A574-73941817B674) +#define LATTICE_INTERFACE uuid(946665F9-71E3-447B-A896-3359DA411532) +#define RECOWORDLIST_INTERFACE uuid(37ADC645-ACE6-4a31-B6A1-FD1F4EF48012) +#define CLASSIC_WISP_INTERFACE uuid(663265C9-6B4D-428c-8266-8058D11C2691) +#define INKOBJECT_INTERFACE uuid(B9C4A0C1-16ED-4DC2-B34A-4E830326587E) +#define INKSTROKE_INTERFACE uuid(251F1257-1DCB-4AD0-A826-4F9E326fE490) +#define INKPOINT_INTERFACE uuid(3776F33D-6BF8-4ADD-9C7E-946AB4A7718D) +#define INKCOLLECT_INTERFACE uuid(E0ABA4C5-1726-4240-8E00-5EE31788A11B) +#define RENDERINK_INTERFACE uuid(538A9C7B-858A-4FF1-9769-62B6D74993D9) +#define INKCLIPBOARD_INTERFACE uuid(D499C1B0-9E97-4CC4-AE10-F8DCCCE1DE09) +#define STROKESET_INTERFACE uuid(2080FF4F-297F-4F66-AA83-CACA65F67216) +#define DRAWATTRS_INTERFACE uuid(051A0FA4-FCEE-4E18-BF46-89726728FB26) +#define TRANSFORMINK_INTERFACE uuid(8341F277-756B-433B-A78E-2221A2577339) +#define STROKEGEOMETERY_INTERFACE uuid(11F962C5-242E-4D4D-B205-0F3AB3562FDE) +#define RENDERINGCONTEXT_INTERFACE uuid(4E6B4F16-5A0C-4815-9AA2-DE231F5AAA26) +#define INKSETTINGS_INTERFACE uuid(A5558507-9B96-46BA-94ED-982E684A9A6B) +#define TABLETEVENTSINK_INTERFACE uuid(788459C8-26C8-4666-BF57-04AD3A0A5EB5) +#define TABLETEVENTSINK_ASYNC async_uuid(CDF7D7D6-2E5D-47c7-90FC-C638C7FA3FC4) +#define TABLETMANAGER_INTERFACE uuid(764DE8AA-1867-47C1-8F6A-122445ABD89A) +#define TABLET_INTERFACE uuid(1CB2EFC3-ABC7-4172-8FCB-3BC9CB93E29F) +#define TABLET2_INTERFACE uuid(C247F616-BBEB-406A-AED3-F75E656599AE) +#define TABLETSETTINGS_INTERFACE uuid(120ae7c9-36f7-4be6-93da-e5f266847b01) +#define TABLETCONTEXT_INTERFACE uuid(45AAAF04-9D6F-41AE-8ED1-ECD6D4B2F17F) +#define TABLETCURSOR_INTERFACE uuid(EF9953C6-B472-4B02-9D22-D0E247ADE0E8) +#define TABLETCURSORBUTTON_INTERFACE uuid(997A992E-8B6C-4945-BC17-A1EE563B3AB7) + +// +// Classic WISP APIs. These GUIDs are different between 1.0 and 2.0 +// +#define WISP_CLIENT_TYPELIB uuid(D48CA453-5D1A-4BF9-B9BA-6CE8CB16F10A) +#define TABLETMANAGER_CLASS uuid(786CDB70-1628-44A0-853C-5D340A499137) +#define CLASSIC_WISP_TYPELIB uuid(DFD61F94-B7C7-4e15-8F27-0F2C9BCB420C) +#define CLASSIC_WISP_CLASS uuid(3336B8BF-45AF-429f-85CB-8C435FBF21E4) +#define RECOCOM_TYPELIB uuid(9E52A566-D72F-4342-99B9-DBCA6780385F) +#define RECOMANAGER_CLASS uuid(DE815B00-9460-4F6E-9471-892ED2275EA5) +#define USERLEXICONMANAGER_CLASS uuid(176D323D-E591-4535-9A09-26F698E5AC5D) +#define GENERICRECOGNIZER_CLASS uuid(EFB4A0CB-A01F-451C-B6B7-56F02F77D76F) +#define LATTICE_CLASS uuid(632A2D3D-86AF-411A-8654-7511B51B3D5F) +#define RECOUSERDICT_CLASS uuid(836FA1B6-1190-4005-B434-7ED921BE2026) +#define TPCINK_TYPELIB uuid(194508A0-B8D1-473E-A9B6-851AAF726A6D) +#define INKOBJECT_CLASS uuid(3EE60F5C-9BAD-4CD8-8E21-AD2D001D06EB) +#define INKSETTINGS_CLASS uuid(242025BB-8546-48B6-B9B0-F4406C54ACFC) +#define DRAWATTRS_CLASS uuid(524B13ED-2E57-40B8-B801-5FA35122EB5C) +#define INKSTROKE_CLASS uuid(4831CABD-F171-47F1-8D3C-0CBC8AFCB788) +#define STROKESET_CLASS uuid(DC4D7DD2-97B1-4CD5-BD6E-E34DD57F767D) +#define RENDERINGCONTEXT_CLASS uuid(07081630-B202-4C48-B8B7-4F6C99B8CACE) +#define TABLET_TYPELIB uuid(C3F76406-6CA5-4BCD-85E4-0E7F9E05D508) + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptics.h b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptics.h new file mode 100644 index 00000000000..ed0fe1af6c8 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptics.h @@ -0,0 +1,1366 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0498 */ +/* Compiler settings for wisptics.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __wisptics_h__ +#define __wisptics_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ITabletManagerP_FWD_DEFINED__ +#define __ITabletManagerP_FWD_DEFINED__ +typedef interface ITabletManagerP ITabletManagerP; +#endif /* __ITabletManagerP_FWD_DEFINED__ */ + + +#ifndef __ITabletManagerDrt_FWD_DEFINED__ +#define __ITabletManagerDrt_FWD_DEFINED__ +typedef interface ITabletManagerDrt ITabletManagerDrt; +#endif /* __ITabletManagerDrt_FWD_DEFINED__ */ + + +#ifndef __ITabletP_FWD_DEFINED__ +#define __ITabletP_FWD_DEFINED__ +typedef interface ITabletP ITabletP; +#endif /* __ITabletP_FWD_DEFINED__ */ + + +#ifndef __ITabletP2_FWD_DEFINED__ +#define __ITabletP2_FWD_DEFINED__ +typedef interface ITabletP2 ITabletP2; +#endif /* __ITabletP2_FWD_DEFINED__ */ + + +#ifndef __ITabletContextP_FWD_DEFINED__ +#define __ITabletContextP_FWD_DEFINED__ +typedef interface ITabletContextP ITabletContextP; +#endif /* __ITabletContextP_FWD_DEFINED__ */ + + +#ifndef __ITabletCursorP_FWD_DEFINED__ +#define __ITabletCursorP_FWD_DEFINED__ +typedef interface ITabletCursorP ITabletCursorP; +#endif /* __ITabletCursorP_FWD_DEFINED__ */ + + +#ifndef __ITabletCursorButtonP_FWD_DEFINED__ +#define __ITabletCursorButtonP_FWD_DEFINED__ +typedef interface ITabletCursorButtonP ITabletCursorButtonP; +#endif /* __ITabletCursorButtonP_FWD_DEFINED__ */ + + +#ifndef __ITabletEventSinkP_FWD_DEFINED__ +#define __ITabletEventSinkP_FWD_DEFINED__ +typedef interface ITabletEventSinkP ITabletEventSinkP; +#endif /* __ITabletEventSinkP_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "tpcpen.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_wisptics_0000_0000 */ +/* [local] */ + +#pragma once + + + + + + + + +extern RPC_IF_HANDLE __MIDL_itf_wisptics_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_wisptics_0000_0000_v0_0_s_ifspec; + +#ifndef __ITabletManagerP_INTERFACE_DEFINED__ +#define __ITabletManagerP_INTERFACE_DEFINED__ + +/* interface ITabletManagerP */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletManagerP *PTABLETMANAGERP; + + +EXTERN_C const IID IID_ITabletManagerP; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("663C73A5-8715-4499-B809-43689A93086B") + ITabletManagerP : public ITabletManager + { + public: + }; + +#else /* C style interface */ + + typedef struct ITabletManagerPVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletManagerP * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletManagerP * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletManagerP * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDefaultTablet )( + ITabletManagerP * This, + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTabletCount )( + ITabletManagerP * This, + /* [out] */ __RPC__out ULONG *pcTablets); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTablet )( + ITabletManagerP * This, + /* [in] */ ULONG iTablet, + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTabletContextById )( + ITabletManagerP * This, + /* [in] */ TABLET_CONTEXT_ID tcid, + /* [out] */ __RPC__deref_out_opt ITabletContext **ppContext); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCursorById )( + ITabletManagerP * This, + /* [in] */ CURSOR_ID cid, + /* [out] */ __RPC__deref_out_opt ITabletCursor **ppCursor); + + END_INTERFACE + } ITabletManagerPVtbl; + + interface ITabletManagerP + { + CONST_VTBL struct ITabletManagerPVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletManagerP_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletManagerP_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletManagerP_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletManagerP_GetDefaultTablet(This,ppTablet) \ + ( (This)->lpVtbl -> GetDefaultTablet(This,ppTablet) ) + +#define ITabletManagerP_GetTabletCount(This,pcTablets) \ + ( (This)->lpVtbl -> GetTabletCount(This,pcTablets) ) + +#define ITabletManagerP_GetTablet(This,iTablet,ppTablet) \ + ( (This)->lpVtbl -> GetTablet(This,iTablet,ppTablet) ) + +#define ITabletManagerP_GetTabletContextById(This,tcid,ppContext) \ + ( (This)->lpVtbl -> GetTabletContextById(This,tcid,ppContext) ) + +#define ITabletManagerP_GetCursorById(This,cid,ppCursor) \ + ( (This)->lpVtbl -> GetCursorById(This,cid,ppCursor) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletManagerP_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletManagerDrt_INTERFACE_DEFINED__ +#define __ITabletManagerDrt_INTERFACE_DEFINED__ + +/* interface ITabletManagerDrt */ +/* [unique][helpstring][uuid][object] */ + + +EXTERN_C const IID IID_ITabletManagerDrt; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("A56AB812-2AC7-443d-A87A-F1EE1CD5A0E6") + ITabletManagerDrt : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE IsTabletPresent( + __RPC__in BSTR bstrTablet, + /* [out] */ __RPC__out BOOL *pfPresent) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SimulatePacket( + __RPC__in BSTR bstrTablet, + LONG x, + LONG y, + BOOL fCursorDown) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE EnablePacketsTransfer( + BOOL fEnable) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SimulateCursorInRange( + DWORD cursorKey) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SimulateCursorOutOfRange( + DWORD cursorKey) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetTabletRectangle( + __RPC__in BSTR bstrTablet, + /* [out] */ __RPC__out RECT *prc) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE FindTablet( + __RPC__in BSTR bstrTablet, + /* [out] */ __RPC__out ULONG *piTablet) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SimulatePacketWithButton( + __RPC__in BSTR bstrTablet, + LONG x, + LONG y, + BOOL fCursorDown, + BOOL fBarrelButton) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SimulateCursorInRangeForTablet( + __RPC__in BSTR bstrTablet, + DWORD cursorKey) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SimulateCursorOutOfRangeForTablet( + __RPC__in BSTR bstrTablet, + DWORD cursorKey) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE EnsureTablet( + __RPC__in BSTR bstrTablet) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletManagerDrtVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletManagerDrt * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletManagerDrt * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletManagerDrt * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *IsTabletPresent )( + ITabletManagerDrt * This, + __RPC__in BSTR bstrTablet, + /* [out] */ __RPC__out BOOL *pfPresent); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SimulatePacket )( + ITabletManagerDrt * This, + __RPC__in BSTR bstrTablet, + LONG x, + LONG y, + BOOL fCursorDown); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *EnablePacketsTransfer )( + ITabletManagerDrt * This, + BOOL fEnable); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SimulateCursorInRange )( + ITabletManagerDrt * This, + DWORD cursorKey); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SimulateCursorOutOfRange )( + ITabletManagerDrt * This, + DWORD cursorKey); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTabletRectangle )( + ITabletManagerDrt * This, + __RPC__in BSTR bstrTablet, + /* [out] */ __RPC__out RECT *prc); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *FindTablet )( + ITabletManagerDrt * This, + __RPC__in BSTR bstrTablet, + /* [out] */ __RPC__out ULONG *piTablet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SimulatePacketWithButton )( + ITabletManagerDrt * This, + __RPC__in BSTR bstrTablet, + LONG x, + LONG y, + BOOL fCursorDown, + BOOL fBarrelButton); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SimulateCursorInRangeForTablet )( + ITabletManagerDrt * This, + __RPC__in BSTR bstrTablet, + DWORD cursorKey); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SimulateCursorOutOfRangeForTablet )( + ITabletManagerDrt * This, + __RPC__in BSTR bstrTablet, + DWORD cursorKey); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *EnsureTablet )( + ITabletManagerDrt * This, + __RPC__in BSTR bstrTablet); + + END_INTERFACE + } ITabletManagerDrtVtbl; + + interface ITabletManagerDrt + { + CONST_VTBL struct ITabletManagerDrtVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletManagerDrt_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletManagerDrt_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletManagerDrt_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletManagerDrt_IsTabletPresent(This,bstrTablet,pfPresent) \ + ( (This)->lpVtbl -> IsTabletPresent(This,bstrTablet,pfPresent) ) + +#define ITabletManagerDrt_SimulatePacket(This,bstrTablet,x,y,fCursorDown) \ + ( (This)->lpVtbl -> SimulatePacket(This,bstrTablet,x,y,fCursorDown) ) + +#define ITabletManagerDrt_EnablePacketsTransfer(This,fEnable) \ + ( (This)->lpVtbl -> EnablePacketsTransfer(This,fEnable) ) + +#define ITabletManagerDrt_SimulateCursorInRange(This,cursorKey) \ + ( (This)->lpVtbl -> SimulateCursorInRange(This,cursorKey) ) + +#define ITabletManagerDrt_SimulateCursorOutOfRange(This,cursorKey) \ + ( (This)->lpVtbl -> SimulateCursorOutOfRange(This,cursorKey) ) + +#define ITabletManagerDrt_GetTabletRectangle(This,bstrTablet,prc) \ + ( (This)->lpVtbl -> GetTabletRectangle(This,bstrTablet,prc) ) + +#define ITabletManagerDrt_FindTablet(This,bstrTablet,piTablet) \ + ( (This)->lpVtbl -> FindTablet(This,bstrTablet,piTablet) ) + +#define ITabletManagerDrt_SimulatePacketWithButton(This,bstrTablet,x,y,fCursorDown,fBarrelButton) \ + ( (This)->lpVtbl -> SimulatePacketWithButton(This,bstrTablet,x,y,fCursorDown,fBarrelButton) ) + +#define ITabletManagerDrt_SimulateCursorInRangeForTablet(This,bstrTablet,cursorKey) \ + ( (This)->lpVtbl -> SimulateCursorInRangeForTablet(This,bstrTablet,cursorKey) ) + +#define ITabletManagerDrt_SimulateCursorOutOfRangeForTablet(This,bstrTablet,cursorKey) \ + ( (This)->lpVtbl -> SimulateCursorOutOfRangeForTablet(This,bstrTablet,cursorKey) ) + +#define ITabletManagerDrt_EnsureTablet(This,bstrTablet) \ + ( (This)->lpVtbl -> EnsureTablet(This,bstrTablet) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletManagerDrt_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletP_INTERFACE_DEFINED__ +#define __ITabletP_INTERFACE_DEFINED__ + +/* interface ITabletP */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletP *PTABLETP; + + +EXTERN_C const IID IID_ITabletP; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("E65752FA-600B-43bd-8BFE-6A686FA3A201") + ITabletP : public ITablet + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetId( + /* [out] */ __RPC__out DWORD *pId) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletPVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletP * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletP * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletP * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDefaultContextSettings )( + ITabletP * This, + /* [out] */ __RPC__deref_out_opt TABLET_CONTEXT_SETTINGS **ppTCS); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *CreateContext )( + ITabletP * This, + /* [in] */ __RPC__in HWND hWnd, + /* [unique][in] */ __RPC__in_opt RECT *prcInput, + /* [in] */ DWORD dwOptions, + /* [unique][in] */ __RPC__in_opt TABLET_CONTEXT_SETTINGS *pTCS, + /* [in] */ CONTEXT_ENABLE_TYPE cet, + /* [out] */ __RPC__deref_out_opt ITabletContext **ppCtx, + /* [unique][out][in] */ __RPC__inout_opt TABLET_CONTEXT_ID *pTcid, + /* [unique][out][in] */ __RPC__deref_opt_inout_opt PACKET_DESCRIPTION **ppPD, + /* [unique][in] */ __RPC__in_opt ITabletEventSink *pSink); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetName )( + ITabletP * This, + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszName); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMaxInputRect )( + ITabletP * This, + /* [out] */ __RPC__out RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetHardwareCaps )( + ITabletP * This, + /* [out] */ __RPC__out DWORD *pdwCaps); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPropertyMetrics )( + ITabletP * This, + /* [in] */ __RPC__in REFGUID rguid, + /* [out] */ __RPC__out PROPERTY_METRICS *pPM); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPlugAndPlayId )( + ITabletP * This, + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszPPId); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCursorCount )( + ITabletP * This, + /* [out] */ __RPC__out ULONG *pcCurs); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetCursor )( + ITabletP * This, + /* [in] */ ULONG iCur, + /* [out] */ __RPC__deref_out_opt ITabletCursor **ppCur); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetId )( + ITabletP * This, + /* [out] */ __RPC__out DWORD *pId); + + END_INTERFACE + } ITabletPVtbl; + + interface ITabletP + { + CONST_VTBL struct ITabletPVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletP_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletP_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletP_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletP_GetDefaultContextSettings(This,ppTCS) \ + ( (This)->lpVtbl -> GetDefaultContextSettings(This,ppTCS) ) + +#define ITabletP_CreateContext(This,hWnd,prcInput,dwOptions,pTCS,cet,ppCtx,pTcid,ppPD,pSink) \ + ( (This)->lpVtbl -> CreateContext(This,hWnd,prcInput,dwOptions,pTCS,cet,ppCtx,pTcid,ppPD,pSink) ) + +#define ITabletP_GetName(This,ppwszName) \ + ( (This)->lpVtbl -> GetName(This,ppwszName) ) + +#define ITabletP_GetMaxInputRect(This,prcInput) \ + ( (This)->lpVtbl -> GetMaxInputRect(This,prcInput) ) + +#define ITabletP_GetHardwareCaps(This,pdwCaps) \ + ( (This)->lpVtbl -> GetHardwareCaps(This,pdwCaps) ) + +#define ITabletP_GetPropertyMetrics(This,rguid,pPM) \ + ( (This)->lpVtbl -> GetPropertyMetrics(This,rguid,pPM) ) + +#define ITabletP_GetPlugAndPlayId(This,ppwszPPId) \ + ( (This)->lpVtbl -> GetPlugAndPlayId(This,ppwszPPId) ) + +#define ITabletP_GetCursorCount(This,pcCurs) \ + ( (This)->lpVtbl -> GetCursorCount(This,pcCurs) ) + +#define ITabletP_GetCursor(This,iCur,ppCur) \ + ( (This)->lpVtbl -> GetCursor(This,iCur,ppCur) ) + + +#define ITabletP_GetId(This,pId) \ + ( (This)->lpVtbl -> GetId(This,pId) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletP_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletP2_INTERFACE_DEFINED__ +#define __ITabletP2_INTERFACE_DEFINED__ + +/* interface ITabletP2 */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletP2 *PTABLETP2; + + +EXTERN_C const IID IID_ITabletP2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("de5d1ed5-41d4-475d-bdd8-ea749677b3a1") + ITabletP2 : public ITablet2 + { + public: + }; + +#else /* C style interface */ + + typedef struct ITabletP2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletP2 * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletP2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletP2 * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDeviceKind )( + ITabletP2 * This, + /* [out] */ __RPC__out TABLET_DEVICE_KIND *pKind); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetMatchingScreenRect )( + ITabletP2 * This, + /* [out] */ __RPC__out RECT *prcInput); + + END_INTERFACE + } ITabletP2Vtbl; + + interface ITabletP2 + { + CONST_VTBL struct ITabletP2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletP2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletP2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletP2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletP2_GetDeviceKind(This,pKind) \ + ( (This)->lpVtbl -> GetDeviceKind(This,pKind) ) + +#define ITabletP2_GetMatchingScreenRect(This,prcInput) \ + ( (This)->lpVtbl -> GetMatchingScreenRect(This,prcInput) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletP2_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_wisptics_0000_0004 */ +/* [local] */ + +typedef +enum _CONTEXT_TYPE + { WINTAB = 1, + HID = ( WINTAB + 1 ) , + MOUSE = ( HID + 1 ) + } CONTEXT_TYPE; + + + +extern RPC_IF_HANDLE __MIDL_itf_wisptics_0000_0004_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_wisptics_0000_0004_v0_0_s_ifspec; + +#ifndef __ITabletContextP_INTERFACE_DEFINED__ +#define __ITabletContextP_INTERFACE_DEFINED__ + +/* interface ITabletContextP */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletContextP *PTABLETCONTEXTP; + + +EXTERN_C const IID IID_ITabletContextP; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("22F74D0A-694F-4f47-A5CE-AE08A6409AC8") + ITabletContextP : public ITabletContext + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Overlap( + /* [in] */ BOOL bTop, + /* [out] */ __RPC__out DWORD *pdwtcid) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetType( + /* [out] */ __RPC__out CONTEXT_TYPE *pct) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE TrackInputRect( + /* [out] */ __RPC__out RECT *prcInput) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE IsTopMostHook( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetEventSink( + /* [out] */ __RPC__deref_out_opt ITabletEventSink **ppSink) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UseSharedMemoryCommunications( + /* [in] */ DWORD pid, + /* [out] */ __RPC__out DWORD *phEventMoreData, + /* [out] */ __RPC__out DWORD *phEventClientReady, + /* [out] */ __RPC__out DWORD *phMutexAccess, + /* [out] */ __RPC__out DWORD *phFileMapping) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UseNamedSharedMemoryCommunications( + /* [in] */ DWORD pid, + /* [string][in] */ __RPC__in LPCTSTR szSid, + /* [string][in] */ __RPC__in LPCTSTR sdIlSid, + /* [out] */ __RPC__out DWORD *pdwEventMoreDataId, + /* [out] */ __RPC__out DWORD *pdwEventClientReadyId, + /* [out] */ __RPC__out DWORD *pdwMutexAccessId, + /* [out] */ __RPC__out DWORD *pdwFileMappingId) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletContextPVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletContextP * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletContextP * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletContextP * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetId )( + ITabletContextP * This, + /* [out] */ __RPC__out TABLET_CONTEXT_ID *pTcid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetWindow )( + ITabletContextP * This, + /* [out] */ __RPC__deref_out_opt HWND *pHwnd); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetSettings )( + ITabletContextP * This, + /* [out] */ __RPC__deref_out_opt TABLET_CONTEXT_SETTINGS **ppTCS); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTablet )( + ITabletContextP * This, + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Enable )( + ITabletContextP * This, + /* [in] */ CONTEXT_ENABLE_TYPE cet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetOptions )( + ITabletContextP * This, + /* [out] */ __RPC__out DWORD *pdwOptions); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPacketDescription )( + ITabletContextP * This, + /* [out] */ __RPC__deref_out_opt PACKET_DESCRIPTION **ppPD); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetStatus )( + ITabletContextP * This, + /* [out] */ __RPC__out DWORD *pdwStatus); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetInputRect )( + ITabletContextP * This, + /* [out] */ __RPC__out RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetInputRect )( + ITabletContextP * This, + /* [unique][in] */ __RPC__in_opt RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetDevInputRect )( + ITabletContextP * This, + /* [unique][in] */ __RPC__in_opt RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetDevInputRect )( + ITabletContextP * This, + /* [out] */ __RPC__out RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetCapture )( + ITabletContextP * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ReleaseCapture )( + ITabletContextP * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *SetCursorCapture )( + ITabletContextP * This, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ReleaseCursorCapture )( + ITabletContextP * This, + /* [in] */ CURSOR_ID cid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPackets )( + ITabletContextP * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [out][in] */ __RPC__inout ULONG *pcPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][out] */ __RPC__out_ecount_full(cbPkts) BYTE *pbPkts, + /* [out] */ __RPC__out CURSOR_ID *pCid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *PeekPackets )( + ITabletContextP * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [out][in] */ __RPC__inout ULONG *pcPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][out] */ __RPC__out_ecount_full(cbPkts) BYTE *pbPkts, + /* [out] */ __RPC__out CURSOR_ID *pCid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *FlushPackets )( + ITabletContextP * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *FlushQueue )( + ITabletContextP * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPacketCount )( + ITabletContextP * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [out] */ __RPC__out ULONG *pcPkts); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetPacketQueueInfo )( + ITabletContextP * This, + /* [out] */ __RPC__out ULONG *pnBegin, + /* [out] */ __RPC__out ULONG *pnEnd, + /* [out] */ __RPC__out ULONG *pcPkts); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ForwardPackets )( + ITabletContextP * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *InjectPackets )( + ITabletContextP * This, + /* [in] */ ULONG cPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cPkts) CURSOR_ID *pCids); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ModifyPackets )( + ITabletContextP * This, + /* [in] */ ULONG nBegin, + /* [in] */ ULONG nEnd, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *ConvertToScreenCoordinates )( + ITabletContextP * This, + /* [in] */ ULONG cPkts, + /* [in] */ ULONG cbPkts, + /* [size_is][in] */ __RPC__in_ecount_full(cbPkts) BYTE *pbPkts, + /* [size_is][out] */ __RPC__out_ecount_full(cPkts) POINT *pPointsInScreen); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *Overlap )( + ITabletContextP * This, + /* [in] */ BOOL bTop, + /* [out] */ __RPC__out DWORD *pdwtcid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetType )( + ITabletContextP * This, + /* [out] */ __RPC__out CONTEXT_TYPE *pct); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *TrackInputRect )( + ITabletContextP * This, + /* [out] */ __RPC__out RECT *prcInput); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *IsTopMostHook )( + ITabletContextP * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetEventSink )( + ITabletContextP * This, + /* [out] */ __RPC__deref_out_opt ITabletEventSink **ppSink); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *UseSharedMemoryCommunications )( + ITabletContextP * This, + /* [in] */ DWORD pid, + /* [out] */ __RPC__out DWORD *phEventMoreData, + /* [out] */ __RPC__out DWORD *phEventClientReady, + /* [out] */ __RPC__out DWORD *phMutexAccess, + /* [out] */ __RPC__out DWORD *phFileMapping); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *UseNamedSharedMemoryCommunications )( + ITabletContextP * This, + /* [in] */ DWORD pid, + /* [string][in] */ __RPC__in LPCTSTR szSid, + /* [string][in] */ __RPC__in LPCTSTR sdIlSid, + /* [out] */ __RPC__out DWORD *pdwEventMoreDataId, + /* [out] */ __RPC__out DWORD *pdwEventClientReadyId, + /* [out] */ __RPC__out DWORD *pdwMutexAccessId, + /* [out] */ __RPC__out DWORD *pdwFileMappingId); + + END_INTERFACE + } ITabletContextPVtbl; + + interface ITabletContextP + { + CONST_VTBL struct ITabletContextPVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletContextP_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletContextP_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletContextP_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletContextP_GetId(This,pTcid) \ + ( (This)->lpVtbl -> GetId(This,pTcid) ) + +#define ITabletContextP_GetWindow(This,pHwnd) \ + ( (This)->lpVtbl -> GetWindow(This,pHwnd) ) + +#define ITabletContextP_GetSettings(This,ppTCS) \ + ( (This)->lpVtbl -> GetSettings(This,ppTCS) ) + +#define ITabletContextP_GetTablet(This,ppTablet) \ + ( (This)->lpVtbl -> GetTablet(This,ppTablet) ) + +#define ITabletContextP_Enable(This,cet) \ + ( (This)->lpVtbl -> Enable(This,cet) ) + +#define ITabletContextP_GetOptions(This,pdwOptions) \ + ( (This)->lpVtbl -> GetOptions(This,pdwOptions) ) + +#define ITabletContextP_GetPacketDescription(This,ppPD) \ + ( (This)->lpVtbl -> GetPacketDescription(This,ppPD) ) + +#define ITabletContextP_GetStatus(This,pdwStatus) \ + ( (This)->lpVtbl -> GetStatus(This,pdwStatus) ) + +#define ITabletContextP_GetInputRect(This,prcInput) \ + ( (This)->lpVtbl -> GetInputRect(This,prcInput) ) + +#define ITabletContextP_SetInputRect(This,prcInput) \ + ( (This)->lpVtbl -> SetInputRect(This,prcInput) ) + +#define ITabletContextP_SetDevInputRect(This,prcInput) \ + ( (This)->lpVtbl -> SetDevInputRect(This,prcInput) ) + +#define ITabletContextP_GetDevInputRect(This,prcInput) \ + ( (This)->lpVtbl -> GetDevInputRect(This,prcInput) ) + +#define ITabletContextP_SetCapture(This) \ + ( (This)->lpVtbl -> SetCapture(This) ) + +#define ITabletContextP_ReleaseCapture(This) \ + ( (This)->lpVtbl -> ReleaseCapture(This) ) + +#define ITabletContextP_SetCursorCapture(This,cid) \ + ( (This)->lpVtbl -> SetCursorCapture(This,cid) ) + +#define ITabletContextP_ReleaseCursorCapture(This,cid) \ + ( (This)->lpVtbl -> ReleaseCursorCapture(This,cid) ) + +#define ITabletContextP_GetPackets(This,nBegin,nEnd,pcPkts,cbPkts,pbPkts,pCid) \ + ( (This)->lpVtbl -> GetPackets(This,nBegin,nEnd,pcPkts,cbPkts,pbPkts,pCid) ) + +#define ITabletContextP_PeekPackets(This,nBegin,nEnd,pcPkts,cbPkts,pbPkts,pCid) \ + ( (This)->lpVtbl -> PeekPackets(This,nBegin,nEnd,pcPkts,cbPkts,pbPkts,pCid) ) + +#define ITabletContextP_FlushPackets(This,nBegin,nEnd) \ + ( (This)->lpVtbl -> FlushPackets(This,nBegin,nEnd) ) + +#define ITabletContextP_FlushQueue(This) \ + ( (This)->lpVtbl -> FlushQueue(This) ) + +#define ITabletContextP_GetPacketCount(This,nBegin,nEnd,pcPkts) \ + ( (This)->lpVtbl -> GetPacketCount(This,nBegin,nEnd,pcPkts) ) + +#define ITabletContextP_GetPacketQueueInfo(This,pnBegin,pnEnd,pcPkts) \ + ( (This)->lpVtbl -> GetPacketQueueInfo(This,pnBegin,pnEnd,pcPkts) ) + +#define ITabletContextP_ForwardPackets(This,nBegin,nEnd) \ + ( (This)->lpVtbl -> ForwardPackets(This,nBegin,nEnd) ) + +#define ITabletContextP_InjectPackets(This,cPkts,cbPkts,pbPkts,pCids) \ + ( (This)->lpVtbl -> InjectPackets(This,cPkts,cbPkts,pbPkts,pCids) ) + +#define ITabletContextP_ModifyPackets(This,nBegin,nEnd,cbPkts,pbPkts) \ + ( (This)->lpVtbl -> ModifyPackets(This,nBegin,nEnd,cbPkts,pbPkts) ) + +#define ITabletContextP_ConvertToScreenCoordinates(This,cPkts,cbPkts,pbPkts,pPointsInScreen) \ + ( (This)->lpVtbl -> ConvertToScreenCoordinates(This,cPkts,cbPkts,pbPkts,pPointsInScreen) ) + + +#define ITabletContextP_Overlap(This,bTop,pdwtcid) \ + ( (This)->lpVtbl -> Overlap(This,bTop,pdwtcid) ) + +#define ITabletContextP_GetType(This,pct) \ + ( (This)->lpVtbl -> GetType(This,pct) ) + +#define ITabletContextP_TrackInputRect(This,prcInput) \ + ( (This)->lpVtbl -> TrackInputRect(This,prcInput) ) + +#define ITabletContextP_IsTopMostHook(This) \ + ( (This)->lpVtbl -> IsTopMostHook(This) ) + +#define ITabletContextP_GetEventSink(This,ppSink) \ + ( (This)->lpVtbl -> GetEventSink(This,ppSink) ) + +#define ITabletContextP_UseSharedMemoryCommunications(This,pid,phEventMoreData,phEventClientReady,phMutexAccess,phFileMapping) \ + ( (This)->lpVtbl -> UseSharedMemoryCommunications(This,pid,phEventMoreData,phEventClientReady,phMutexAccess,phFileMapping) ) + +#define ITabletContextP_UseNamedSharedMemoryCommunications(This,pid,szSid,sdIlSid,pdwEventMoreDataId,pdwEventClientReadyId,pdwMutexAccessId,pdwFileMappingId) \ + ( (This)->lpVtbl -> UseNamedSharedMemoryCommunications(This,pid,szSid,sdIlSid,pdwEventMoreDataId,pdwEventClientReadyId,pdwMutexAccessId,pdwFileMappingId) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletContextP_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletCursorP_INTERFACE_DEFINED__ +#define __ITabletCursorP_INTERFACE_DEFINED__ + +/* interface ITabletCursorP */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletCursorP *PTABLETCURSORP; + + +EXTERN_C const IID IID_ITabletCursorP; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("35DE0002-232C-4629-A915-7E600E80CD88") + ITabletCursorP : public ITabletCursor + { + public: + }; + +#else /* C style interface */ + + typedef struct ITabletCursorPVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletCursorP * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletCursorP * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletCursorP * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetName )( + ITabletCursorP * This, + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszName); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *IsInverted )( + ITabletCursorP * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetId )( + ITabletCursorP * This, + /* [out] */ __RPC__out CURSOR_ID *pCid); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetTablet )( + ITabletCursorP * This, + /* [out] */ __RPC__deref_out_opt ITablet **ppTablet); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetButtonCount )( + ITabletCursorP * This, + /* [out] */ __RPC__out ULONG *pcButtons); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetButton )( + ITabletCursorP * This, + /* [in] */ ULONG iButton, + /* [out] */ __RPC__deref_out_opt ITabletCursorButton **ppButton); + + END_INTERFACE + } ITabletCursorPVtbl; + + interface ITabletCursorP + { + CONST_VTBL struct ITabletCursorPVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletCursorP_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletCursorP_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletCursorP_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletCursorP_GetName(This,ppwszName) \ + ( (This)->lpVtbl -> GetName(This,ppwszName) ) + +#define ITabletCursorP_IsInverted(This) \ + ( (This)->lpVtbl -> IsInverted(This) ) + +#define ITabletCursorP_GetId(This,pCid) \ + ( (This)->lpVtbl -> GetId(This,pCid) ) + +#define ITabletCursorP_GetTablet(This,ppTablet) \ + ( (This)->lpVtbl -> GetTablet(This,ppTablet) ) + +#define ITabletCursorP_GetButtonCount(This,pcButtons) \ + ( (This)->lpVtbl -> GetButtonCount(This,pcButtons) ) + +#define ITabletCursorP_GetButton(This,iButton,ppButton) \ + ( (This)->lpVtbl -> GetButton(This,iButton,ppButton) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletCursorP_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletCursorButtonP_INTERFACE_DEFINED__ +#define __ITabletCursorButtonP_INTERFACE_DEFINED__ + +/* interface ITabletCursorButtonP */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletCursorButtonP *PTABLETCURSORBUTTONP; + + +EXTERN_C const IID IID_ITabletCursorButtonP; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("FCA502B0-5409-434d-8C35-A96C76CCA99C") + ITabletCursorButtonP : public ITabletCursorButton + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetId( + /* [out] */ __RPC__out DWORD *pId) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITabletCursorButtonPVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletCursorButtonP * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletCursorButtonP * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletCursorButtonP * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetName )( + ITabletCursorButtonP * This, + /* [out] */ __RPC__deref_out_opt LPWSTR *ppwszName); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetGuid )( + ITabletCursorButtonP * This, + /* [out] */ __RPC__out GUID *pguidBtn); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *GetId )( + ITabletCursorButtonP * This, + /* [out] */ __RPC__out DWORD *pId); + + END_INTERFACE + } ITabletCursorButtonPVtbl; + + interface ITabletCursorButtonP + { + CONST_VTBL struct ITabletCursorButtonPVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletCursorButtonP_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletCursorButtonP_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletCursorButtonP_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITabletCursorButtonP_GetName(This,ppwszName) \ + ( (This)->lpVtbl -> GetName(This,ppwszName) ) + +#define ITabletCursorButtonP_GetGuid(This,pguidBtn) \ + ( (This)->lpVtbl -> GetGuid(This,pguidBtn) ) + + +#define ITabletCursorButtonP_GetId(This,pId) \ + ( (This)->lpVtbl -> GetId(This,pId) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletCursorButtonP_INTERFACE_DEFINED__ */ + + +#ifndef __ITabletEventSinkP_INTERFACE_DEFINED__ +#define __ITabletEventSinkP_INTERFACE_DEFINED__ + +/* interface ITabletEventSinkP */ +/* [unique][helpstring][uuid][object] */ + +typedef ITabletEventSinkP *PTABLETEVENTSINKP; + + +EXTERN_C const IID IID_ITabletEventSinkP; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("287A9E67-8D1D-4a65-8DB4-51915395D019") + ITabletEventSinkP : public IUnknown + { + public: + }; + +#else /* C style interface */ + + typedef struct ITabletEventSinkPVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITabletEventSinkP * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITabletEventSinkP * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITabletEventSinkP * This); + + END_INTERFACE + } ITabletEventSinkPVtbl; + + interface ITabletEventSinkP + { + CONST_VTBL struct ITabletEventSinkPVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITabletEventSinkP_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITabletEventSinkP_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITabletEventSinkP_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITabletEventSinkP_INTERFACE_DEFINED__ */ + + +/* Additional Prototypes for ALL interfaces */ + +unsigned long __RPC_USER BSTR_UserSize( unsigned long *, unsigned long , BSTR * ); +unsigned char * __RPC_USER BSTR_UserMarshal( unsigned long *, unsigned char *, BSTR * ); +unsigned char * __RPC_USER BSTR_UserUnmarshal(unsigned long *, unsigned char *, BSTR * ); +void __RPC_USER BSTR_UserFree( unsigned long *, BSTR * ); + +unsigned long __RPC_USER BSTR_UserSize64( unsigned long *, unsigned long , BSTR * ); +unsigned char * __RPC_USER BSTR_UserMarshal64( unsigned long *, unsigned char *, BSTR * ); +unsigned char * __RPC_USER BSTR_UserUnmarshal64(unsigned long *, unsigned char *, BSTR * ); +void __RPC_USER BSTR_UserFree64( unsigned long *, BSTR * ); + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptics_i.c b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptics_i.c new file mode 100644 index 00000000000..5c3540ba631 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptics_i.c @@ -0,0 +1,104 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 7.00.0498 */ +/* Compiler settings for wisptics.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, IID_ITabletManagerP,0x663C73A5,0x8715,0x4499,0xB8,0x09,0x43,0x68,0x9A,0x93,0x08,0x6B); + + +MIDL_DEFINE_GUID(IID, IID_ITabletManagerDrt,0xA56AB812,0x2AC7,0x443d,0xA8,0x7A,0xF1,0xEE,0x1C,0xD5,0xA0,0xE6); + + +MIDL_DEFINE_GUID(IID, IID_ITabletP,0xE65752FA,0x600B,0x43bd,0x8B,0xFE,0x6A,0x68,0x6F,0xA3,0xA2,0x01); + + +MIDL_DEFINE_GUID(IID, IID_ITabletP2,0xde5d1ed5,0x41d4,0x475d,0xbd,0xd8,0xea,0x74,0x96,0x77,0xb3,0xa1); + + +MIDL_DEFINE_GUID(IID, IID_ITabletContextP,0x22F74D0A,0x694F,0x4f47,0xA5,0xCE,0xAE,0x08,0xA6,0x40,0x9A,0xC8); + + +MIDL_DEFINE_GUID(IID, IID_ITabletCursorP,0x35DE0002,0x232C,0x4629,0xA9,0x15,0x7E,0x60,0x0E,0x80,0xCD,0x88); + + +MIDL_DEFINE_GUID(IID, IID_ITabletCursorButtonP,0xFCA502B0,0x5409,0x434d,0x8C,0x35,0xA9,0x6C,0x76,0xCC,0xA9,0x9C); + + +MIDL_DEFINE_GUID(IID, IID_ITabletEventSinkP,0x287A9E67,0x8D1D,0x4a65,0x8D,0xB4,0x51,0x91,0x53,0x95,0xD0,0x19); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptis.h b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptis.h new file mode 100644 index 00000000000..be8bd2e45a6 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptis.h @@ -0,0 +1,119 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0498 */ +/* Compiler settings for wisptis.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + + +#ifndef __wisptis_h__ +#define __wisptis_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __TabletManagerS_FWD_DEFINED__ +#define __TabletManagerS_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class TabletManagerS TabletManagerS; +#else +typedef struct TabletManagerS TabletManagerS; +#endif /* __cplusplus */ + +#endif /* __TabletManagerS_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "tpcpen.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + + +#ifndef __WISPTISLib_LIBRARY_DEFINED__ +#define __WISPTISLib_LIBRARY_DEFINED__ + +/* library WISPTISLib */ +/* [helpstring][version][uuid] */ + + + + + + + + +EXTERN_C const IID LIBID_WISPTISLib; + +EXTERN_C const CLSID CLSID_TabletManagerS; + +#ifdef __cplusplus + +class DECLSPEC_UUID("A5B020FD-E04B-4e67-B65A-E7DEED25B2CF") +TabletManagerS; +#endif +#endif /* __WISPTISLib_LIBRARY_DEFINED__ */ + +/* interface __MIDL_itf_wisptis_0000_0000 */ +/* [local] */ + +#define SZ_REGKEY_PROFILE TEXT("Software\\Microsoft\\Wisp\\Pen\\Profile") + + +extern RPC_IF_HANDLE __MIDL_itf_wisptis_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_wisptis_0000_0000_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptis_i.c b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptis_i.c new file mode 100644 index 00000000000..f3ba1b7a837 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/inc/wisptis_i.c @@ -0,0 +1,86 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 7.00.0498 */ +/* Compiler settings for wisptis.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, LIBID_WISPTISLib,0x773F1B9A,0x35B9,0x4E95,0x83,0xA0,0xA2,0x10,0xF2,0xDE,0x3B,0x37); + + +MIDL_DEFINE_GUID(CLSID, CLSID_TabletManagerS,0xA5B020FD,0xE04B,0x4e67,0xB6,0x5A,0xE7,0xDE,0xED,0x25,0xB2,0xCF); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/TabLib.vcxproj b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/TabLib.vcxproj new file mode 100644 index 00000000000..ccc746299f3 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/TabLib.vcxproj @@ -0,0 +1,49 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + StaticLibrary + false + + + + 15.0 + {8F91EB3A-C530-4CEA-90BF-AFC8165B6456} + Win32Proj + TabLib + + + + + + + + + NotUsing + %(AdditionalIncludeDirectories);$(WpfSourceDir)PenImc\inc\ + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/dir.targets b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/dir.targets new file mode 100644 index 00000000000..5236e7c6faf --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/dir.targets @@ -0,0 +1,3 @@ + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/scope.h b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/scope.h new file mode 100644 index 00000000000..399a02d3206 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/scope.h @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + +#pragma once + +template +class Scope +{ + public: + Scope() : + m_t(P::DefaultValue()) + { + } + + Scope(const T& t) : + m_t(t) + { + } + + ~Scope() + { + P::Close(m_t); + } + + public: + T& get() + { + return m_t; + } + + public: + operator T() + { + return m_t; + } + + bool operator==(const T& t) const + { + return m_t == t; + } + + bool operator!=(const T& t) const + { + return m_t != t; + } + + private: + T m_t; + + private: //not implemented + Scope(const Scope& o) {} + Scope& operator=(const Scope& o) {} +}; + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/scopes.h b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/scopes.h new file mode 100644 index 00000000000..ef45551e85c --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/scopes.h @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + +#pragma once + +#include "scope.h" + +template +class ScopedArrayPolicy +{ + public: + static T DefaultValue() + { + return NULL; + } + + static void Close(T t) + { + delete [] t; + } +}; + +typedef Scope > ScopedString; + +template +class ScopedLocalPolicy +{ + public: + static T DefaultValue() + { + return NULL; + } + + static void Close(T t) + { + LocalFree(t); + } +}; + +typedef Scope > ScopedLocalString; + +typedef Scope > ScopedSecurityDescriptor; + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/sidutils.cpp b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/sidutils.cpp new file mode 100644 index 00000000000..8ac7f722235 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/sidutils.cpp @@ -0,0 +1,198 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + +#include "sidutils.h" +#include "sddl.h" +#include + +HRESULT +GetUserSid(__inout LPTSTR* sid) +{ + ASSERT(sid != NULL); + + if(sid == NULL) + return E_POINTER; + + HRESULT hr = E_FAIL; + + HANDLE hToken = NULL; + BOOL bResult = OpenProcessToken( + GetCurrentProcess(), + TOKEN_QUERY, + &hToken); + + if(bResult) + { + DWORD dwLength = 0; + bResult = GetTokenInformation( + hToken, + TokenUser, + NULL, + 0, + &dwLength); + + if(!bResult && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + TOKEN_USER* ptu = (TOKEN_USER*)new char[dwLength]; + + if(ptu != NULL) + { + bResult = GetTokenInformation( + hToken, + TokenUser, + ptu, + dwLength, + &dwLength); + + if(bResult) + { + bResult = ConvertSidToStringSid(ptu->User.Sid, sid); + + if(bResult) + hr = S_OK; + } + + delete [] (char*)ptu; + } + } + + CloseHandle(hToken); + } + + return hr; +} + + +HRESULT +GetMandatoryLabel(__inout LPTSTR* sid) +{ + ASSERT(sid != NULL); + + if(sid == NULL) + return E_POINTER; + + HRESULT hr = E_FAIL; + + HANDLE hToken = NULL; + BOOL bResult = OpenProcessToken( + GetCurrentProcess(), + TOKEN_QUERY, + &hToken); + + if(bResult) + { + DWORD dwLength = 0; + bResult = GetTokenInformation( + hToken, + TokenIntegrityLevel, + NULL, + 0, + &dwLength); + + if(!bResult && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + TOKEN_MANDATORY_LABEL* ptml = (TOKEN_MANDATORY_LABEL*)new char[dwLength]; + + if(ptml != NULL) + { + bResult = GetTokenInformation( + hToken, + TokenIntegrityLevel, + ptml, + dwLength, + &dwLength); + + if(bResult) + { + bResult = ConvertSidToStringSid(ptml->Label.Sid, sid); + + if(bResult) + hr = S_OK; + } + + delete [] (char*)ptml; + } + } + + CloseHandle(hToken); + } + + return hr; +} + +HRESULT +GetLogonSessionSid(__inout LPTSTR* sid) +{ + ASSERT(sid != NULL); + + if(sid == NULL) + return E_POINTER; + + HRESULT hr = E_FAIL; + + HANDLE hToken = NULL; + BOOL bResult = OpenProcessToken( + GetCurrentProcess(), + TOKEN_QUERY, + &hToken); + + if(bResult) + { + hr = GetLogonSessionSid(hToken, sid); + CloseHandle(hToken); + } + + return hr; +} + +HRESULT +GetLogonSessionSid(HANDLE hToken, __inout LPTSTR* sid) +{ + ASSERT(sid != NULL); + + if(sid == NULL) + return E_POINTER; + + HRESULT hr = E_FAIL; + + DWORD dwLength = 0; + BOOL bResult = GetTokenInformation( + hToken, + TokenLogonSid, + NULL, + 0, + &dwLength); + + if(!bResult && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + TOKEN_GROUPS* ptg = (TOKEN_GROUPS*)new char[dwLength]; + + if(ptg != NULL) + { + bResult = GetTokenInformation( + hToken, + TokenLogonSid, + ptg, + dwLength, + &dwLength); + + if(bResult && ptg->GroupCount == 1) + { + PSID pSid = ptg->Groups[0].Sid; + + bResult = ConvertSidToStringSid(pSid, sid); + + if(bResult) + hr = S_OK; + } + + delete [] (char*)ptg; + } + } + + return hr; +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/sidutils.h b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/sidutils.h new file mode 100644 index 00000000000..9890afb6299 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PenImc/tablib/sidutils.h @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + + +#pragma once + +#include "windows.h" + +// sid must be freed via LocalFree +HRESULT GetUserSid(__inout LPTSTR* sid); +HRESULT GetMandatoryLabel(__inout LPTSTR* sid); +HRESULT GetLogonSessionSid(__inout LPTSTR* sid); +HRESULT GetLogonSessionSid(HANDLE hToken, __inout LPTSTR* sid); + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TrustManagement/readme.txt b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TrustManagement/readme.txt deleted file mode 100644 index cc47ba8189e..00000000000 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TrustManagement/readme.txt +++ /dev/null @@ -1 +0,0 @@ -TrustManagement files used to live here.