diff --git a/.gitignore b/.gitignore index 7fdd94d8..7bde9b6e 100644 --- a/.gitignore +++ b/.gitignore @@ -262,4 +262,3 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ *.pyc -/Sampler diff --git a/AcousticEchoCancellation/AECCapture.cs b/AcousticEchoCancellation/AECCapture.cs index 81fe91c4..3acc4703 100644 --- a/AcousticEchoCancellation/AECCapture.cs +++ b/AcousticEchoCancellation/AECCapture.cs @@ -26,7 +26,7 @@ public CAECCapture() // Set the category as communications. AudioClientProperties clientProperties = new() { - cbSize = (uint)Marshal.SizeOf(typeof(AudioClientProperties)), + cbSize = (uint)Marshal.SizeOf(), eCategory = AUDIO_STREAM_CATEGORY.AudioCategory_Communications }; audioClient.SetClientProperties(clientProperties); diff --git a/CimFSAPI/app.cs b/CimFSAPI/app.cs index 16daa734..a96b2252 100644 --- a/CimFSAPI/app.cs +++ b/CimFSAPI/app.cs @@ -535,7 +535,7 @@ static void ValidateHardLinkInCim([In] string cimPath, [In] string imageName, [I CimFileData cimFileData = GetFileData(cimFilePath); CimFileData cimLinkData = GetFileData(cimLinkPath); - if (Interop.memcmp(cimFileData.FileIdInfo.FileId.Identifier, cimLinkData.FileIdInfo.FileId.Identifier, Marshal.SizeOf(typeof(FILE_ID_128))) != 0) + if (Interop.memcmp(cimFileData.FileIdInfo.FileId.Identifier, cimLinkData.FileIdInfo.FileId.Identifier, Marshal.SizeOf()) != 0) { Console.Error.WriteLine("did not match"); } diff --git a/CustomResourceManager/CSecInfo.cs b/CustomResourceManager/CSecInfo.cs index 04832742..4a90c68c 100644 --- a/CustomResourceManager/CSecInfo.cs +++ b/CustomResourceManager/CSecInfo.cs @@ -442,7 +442,7 @@ public HRESULT SetSecurity(SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR pSD) if (destDacl.IsNull) { // Align sizeNeeded to a uint - var dwSizeNeeded = (Marshal.SizeOf(typeof(ACL)) + (Marshal.SizeOf(typeof(uint)) - 1)) & 0xfffffffc; + var dwSizeNeeded = (Marshal.SizeOf() + (Marshal.SizeOf() - 1)) & 0xfffffffc; pDestDacl = new SafePACL((int)dwSizeNeeded); } diff --git a/CustomResourceManager/utility.cs b/CustomResourceManager/utility.cs index f8fb590c..4f599872 100644 --- a/CustomResourceManager/utility.cs +++ b/CustomResourceManager/utility.cs @@ -85,7 +85,7 @@ public static HRESULT ACEAlreadyInACL(in PACL acl, in PACE ace, out bool lpbAceP continue; } - var result = memcmp(sidStart1, sidStart2, aceSize - Marshal.SizeOf(typeof(ACE_HEADER)) - Marshal.SizeOf(typeof(ACCESS_MASK))); + var result = memcmp(sidStart1, sidStart2, aceSize - Marshal.SizeOf() - Marshal.SizeOf()); if (result == 0) { lpbAcePresent = true; diff --git a/DPIAwarenessPerWindow/client/DpiAwarenessContext.cs b/DPIAwarenessPerWindow/client/DpiAwarenessContext.cs index df8c912c..b5742d9c 100644 --- a/DPIAwarenessPerWindow/client/DpiAwarenessContext.cs +++ b/DPIAwarenessPerWindow/client/DpiAwarenessContext.cs @@ -296,7 +296,7 @@ private static void ShowFileOpenDialog(HWND hWnd) SafeLPTSTR szFile = new(MAX_PATH); // buffer for file name OPENFILENAME ofn = new() { - lStructSize = (uint)Marshal.SizeOf(typeof(OPENFILENAME)), + lStructSize = (uint)Marshal.SizeOf(), hwndOwner = hWnd, lpstrFile = szFile, nMaxFile = (uint)szFile.Capacity, diff --git a/DPIAwarenessPerWindow/client/DpiAwarenessContextRes.dll b/DPIAwarenessPerWindow/client/DpiAwarenessContextRes.dll index 9032f517..e924394d 100644 Binary files a/DPIAwarenessPerWindow/client/DpiAwarenessContextRes.dll and b/DPIAwarenessPerWindow/client/DpiAwarenessContextRes.dll differ diff --git a/DXGIDesktopDuplication/DisplayManager.cs b/DXGIDesktopDuplication/DisplayManager.cs index 4d9da50c..96e0aba6 100644 --- a/DXGIDesktopDuplication/DisplayManager.cs +++ b/DXGIDesktopDuplication/DisplayManager.cs @@ -50,7 +50,7 @@ public DUPL_RETURN ProcessFrame(in FRAME_DATA Data, [In, Out] ID3D11Texture2D Sh } if (Data.DirtyCount != 0) { - Ret = CopyDirty(Data.Frame, SharedSurf, Data.MetaData.Offset(Data.MoveCount * Marshal.SizeOf(typeof(DXGI_OUTDUPL_MOVE_RECT))).ToArray(Data.DirtyCount)!, Data.DirtyCount, OffsetX, OffsetY, DeskDesc); + Ret = CopyDirty(Data.Frame, SharedSurf, Data.MetaData.Offset(Data.MoveCount * Marshal.SizeOf()).ToArray(Data.DirtyCount)!, Data.DirtyCount, OffsetX, OffsetY, DeskDesc); } } return Ret; @@ -341,7 +341,7 @@ DUPL_RETURN CopyDirty([In] ID3D11Texture2D SrcSurface, [In, Out] ID3D11Texture2D { return ProcessFailure(m_Device, "Failed to create vertex buffer in dirty rect processing", "Error", hr, SystemTransitionsExpectedErrors); } - uint Stride = (uint)Marshal.SizeOf(typeof(VERTEX)); + uint Stride = (uint)Marshal.SizeOf(); uint Offset = 0; m_DeviceContext.IASetVertexBuffers(0, 1, [VertBuf!], [Stride], [Offset]); diff --git a/DXGIDesktopDuplication/DuplicationManager.cs b/DXGIDesktopDuplication/DuplicationManager.cs index 505cf734..ab4ab962 100644 --- a/DXGIDesktopDuplication/DuplicationManager.cs +++ b/DXGIDesktopDuplication/DuplicationManager.cs @@ -202,7 +202,7 @@ public DUPL_RETURN GetFrame(out FRAME_DATA Data, out bool Timeout) Data.DirtyCount = 0; return ProcessFailure(default, "Failed to get frame move rects in DUPLICATIONMANAGER", "Error", hr, FrameInfoExpectedErrors); } - Data.MoveCount = (int)BufSize / Marshal.SizeOf(typeof(DXGI_OUTDUPL_MOVE_RECT)); + Data.MoveCount = (int)BufSize / Marshal.SizeOf(); IntPtr DirtyRects = m_MetaDataBuffer.Offset(BufSize); BufSize = FrameInfo.TotalMetadataBufferSize - BufSize; @@ -215,7 +215,7 @@ public DUPL_RETURN GetFrame(out FRAME_DATA Data, out bool Timeout) Data.DirtyCount = 0; return ProcessFailure(default, "Failed to get frame dirty rects in DUPLICATIONMANAGER", "Error", hr, FrameInfoExpectedErrors); } - Data.DirtyCount = (int)BufSize / Marshal.SizeOf(typeof(RECT)); + Data.DirtyCount = (int)BufSize / Marshal.SizeOf(); Data.MetaData = m_MetaDataBuffer; } diff --git a/DXGIDesktopDuplication/OutputManager.cs b/DXGIDesktopDuplication/OutputManager.cs index e8a97da3..2b32b286 100644 --- a/DXGIDesktopDuplication/OutputManager.cs +++ b/DXGIDesktopDuplication/OutputManager.cs @@ -437,7 +437,7 @@ DUPL_RETURN DrawFrame() } // Set resources - uint Stride = (uint)Marshal.SizeOf(typeof(VERTEX)); + uint Stride = (uint)Marshal.SizeOf(); uint Offset = 0; float[] blendFactor = [0.0f, 0.0f, 0.0f, 0.0f]; m_DeviceContext!.OMSetBlendState(default, blendFactor, 0xffffffff); @@ -451,7 +451,7 @@ DUPL_RETURN DrawFrame() D3D11_BUFFER_DESC BufferDesc = new() { Usage = D3D11_USAGE.D3D11_USAGE_DEFAULT, - ByteWidth = (uint)(Marshal.SizeOf(typeof(VERTEX)) * NUMVERTICES), + ByteWidth = (uint)(Marshal.SizeOf() * NUMVERTICES), BindFlags = D3D11_BIND_FLAG.D3D11_BIND_VERTEX_BUFFER, CPUAccessFlags = 0 }; @@ -581,7 +581,7 @@ DUPL_RETURN ProcessMonoMask(bool IsMono, [In, Out] ref PTR_INFO PtrInfo, out int return ProcessFailure(default, "Failed to allocate memory for new mouse shape buffer.", "Error", HRESULT.E_OUTOFMEMORY); } - uint DesktopPitchInPixels = (uint)MappedSurface.Pitch / (uint)Marshal.SizeOf(typeof(uint)); + uint DesktopPitchInPixels = (uint)MappedSurface.Pitch / (uint)Marshal.SizeOf(); // What to skip (pixel offset) int SkipX = (GivenLeft < 0) ? (-1 * GivenLeft) : (0); @@ -628,7 +628,7 @@ DUPL_RETURN ProcessMonoMask(bool IsMono, [In, Out] ref PTR_INFO PtrInfo, out int for (int Col = 0; Col < PtrWidth; ++Col) { // Set up mask - uint MaskVal = 0xFF000000 & Buffer32[(Col + SkipX) + ((Row + SkipY) * (PtrInfo.ShapeInfo.Pitch / Marshal.SizeOf(typeof(uint))))]; + uint MaskVal = 0xFF000000 & Buffer32[(Col + SkipX) + ((Row + SkipY) * (PtrInfo.ShapeInfo.Pitch / Marshal.SizeOf()))]; if (MaskVal != 0) { // Mask was 0xFF @@ -780,7 +780,7 @@ DUPL_RETURN DrawMouse(PTR_INFO PtrInfo) D3D11_BUFFER_DESC BDesc = new() { Usage = D3D11_USAGE.D3D11_USAGE_DEFAULT, - ByteWidth = (uint)Marshal.SizeOf(typeof(VERTEX)) * NUMVERTICES, + ByteWidth = (uint)Marshal.SizeOf() * NUMVERTICES, BindFlags = D3D11_BIND_FLAG.D3D11_BIND_VERTEX_BUFFER, CPUAccessFlags = 0 }; @@ -800,7 +800,7 @@ DUPL_RETURN DrawMouse(PTR_INFO PtrInfo) // Set resources float[] BlendFactor = new float[4]; - uint Stride = (uint)Marshal.SizeOf(typeof(VERTEX)); + uint Stride = (uint)Marshal.SizeOf(); uint Offset = 0; m_DeviceContext!.IASetVertexBuffers(0, 1, [VertexBufferMouse!], [Stride], [Offset]); m_DeviceContext.OMSetBlendState(m_BlendState, BlendFactor, 0xFFFFFFFF); diff --git a/DataDedupBackupRestore/DedupBackupRestore.cs b/DataDedupBackupRestore/DedupBackupRestore.cs index 866a7351..c96ce1c0 100644 --- a/DataDedupBackupRestore/DedupBackupRestore.cs +++ b/DataDedupBackupRestore/DedupBackupRestore.cs @@ -792,7 +792,7 @@ private static HRESULT GetEventData([In] EVT_HANDLE _event, string dataName, out properties = (PEVT_VARIANT)eventDataBuffer; - result = EvtRender(renderContext, _event, EvtRenderEventValues, Marshal.SizeOf(typeof(eventDataBuffer)), properties, out bufferUsed, out propertyCount); + result = EvtRender(renderContext, _event, EvtRenderEventValues, Marshal.SizeOf(), properties, out bufferUsed, out propertyCount); } } diff --git a/DesktopAutomationDismiss/ShowDesktop.cs b/DesktopAutomationDismiss/ShowDesktop.cs index 75157722..4aeea5e6 100644 --- a/DesktopAutomationDismiss/ShowDesktop.cs +++ b/DesktopAutomationDismiss/ShowDesktop.cs @@ -275,7 +275,7 @@ private static void ShowDesktop() new INPUT { type = INPUTTYPE.INPUT_KEYBOARD, ki = new KEYBDINPUT { wVk = VK_LWIN, dwFlags = KEYEVENTF.KEYEVENTF_KEYUP } }, }; - if (SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT))) != (uint)inputs.Length) + if (SendInput((uint)inputs.Length, inputs, Marshal.SizeOf()) != (uint)inputs.Length) { OutputString("SendInput failed: {0}\n", Win32Error.GetLastError().ToHRESULT()); } diff --git a/DirectX-Graphics-Samples/D3D1211On12/D3D1211On12.cs b/DirectX-Graphics-Samples/D3D1211On12/D3D1211On12.cs index a06b5ecf..8a577a03 100644 --- a/DirectX-Graphics-Samples/D3D1211On12/D3D1211On12.cs +++ b/DirectX-Graphics-Samples/D3D1211On12/D3D1211On12.cs @@ -166,7 +166,7 @@ private void LoadAssets() // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer.GetGPUVirtualAddress(); - m_vertexBufferView.StrideInBytes = (uint)Marshal.SizeOf(typeof(Vertex)); + m_vertexBufferView.StrideInBytes = (uint)Marshal.SizeOf(); m_vertexBufferView.SizeInBytes = vertexBufferSize; } diff --git a/DirectX-Graphics-Samples/D3D12DepthBoundsTest/D3D12DepthBoundsTest.cs b/DirectX-Graphics-Samples/D3D12DepthBoundsTest/D3D12DepthBoundsTest.cs index d95ceaf3..a55dc02b 100644 --- a/DirectX-Graphics-Samples/D3D12DepthBoundsTest/D3D12DepthBoundsTest.cs +++ b/DirectX-Graphics-Samples/D3D12DepthBoundsTest/D3D12DepthBoundsTest.cs @@ -191,7 +191,7 @@ private void LoadAssets() // Initialize the vertex buffer views. m_vertexBufferView.BufferLocation = m_vertexBuffer!.GetGPUVirtualAddress(); - m_vertexBufferView.StrideInBytes = (uint)Marshal.SizeOf(typeof(Vertex)); + m_vertexBufferView.StrideInBytes = (uint)Marshal.SizeOf(); m_vertexBufferView.SizeInBytes = vertexBufferSize; } diff --git a/DirectX-Graphics-Samples/D3D12Fullscreen/D3D12Fullscreen.cs b/DirectX-Graphics-Samples/D3D12Fullscreen/D3D12Fullscreen.cs index 01e8762c..7c1f530a 100644 --- a/DirectX-Graphics-Samples/D3D12Fullscreen/D3D12Fullscreen.cs +++ b/DirectX-Graphics-Samples/D3D12Fullscreen/D3D12Fullscreen.cs @@ -89,13 +89,10 @@ public override void OnKeyDown(VK key) { switch (key) { - // Instrument the Space Bar to toggle between fullscreen states. - // The window message loop callback will receive a WM_SIZE message once the - // window is in the fullscreen state. At that point, the IDXGISwapChain should - // be resized to match the new window size. + // Instrument the Space Bar to toggle between fullscreen states. The window message loop callback will receive a WM_SIZE message + // once the window is in the fullscreen state. At that point, the IDXGISwapChain should be resized to match the new window size. // - // NOTE: ALT+Enter will perform a similar operation; the code below is not - // required to enable that key combination. + // NOTE: ALT+Enter will perform a similar operation; the code below is not required to enable that key combination. case VK.VK_SPACE: if (TearingSupport) { @@ -110,17 +107,15 @@ public override void OnKeyDown(VK key) } catch { - // Transitions to fullscreen mode can fail when running apps over - // terminal services or for some other unexpected reason. Consider - // notifying the user in some way when this happens. + // Transitions to fullscreen mode can fail when running apps over terminal services or for some other unexpected + // reason. Consider notifying the user in some way when this happens. OutputDebugString("Fullscreen transition failed"); Debug.Assert(false); } } break; - // Instrument the Right Arrow key to change the scene rendering resolution - // to the next resolution option. + // Instrument the Right Arrow key to change the scene rendering resolution to the next resolution option. case VK.VK_RIGHT: m_resolutionIndex = (m_resolutionIndex + 1) % (uint)m_resolutionOptionsCount; @@ -131,8 +126,7 @@ public override void OnKeyDown(VK key) LoadSceneResolutionDependentResources(); break; - // Instrument the Left Arrow key to change the scene rendering resolution - // to the previous resolution option. + // Instrument the Left Arrow key to change the scene rendering resolution to the previous resolution option. case VK.VK_LEFT: if (m_resolutionIndex == 0) { @@ -165,8 +159,7 @@ public override void OnRender() PopulateCommandLists(); // Execute the command lists. - ID3D12CommandList[] ppCommandLists = [m_sceneCommandList!, m_postCommandList!]; - m_commandQueue!.ExecuteCommandLists(ppCommandLists.Length, ppCommandLists); + m_commandQueue!.ExecuteCommandLists([m_sceneCommandList!, m_postCommandList!]); } // When using sync interval 0, it is recommended to always pass the tearing flag when it is supported, even when presenting @@ -174,7 +167,7 @@ public override void OnRender() DXGI_PRESENT presentFlags = (TearingSupport && m_windowedMode) ? DXGI_PRESENT.DXGI_PRESENT_ALLOW_TEARING : 0; // Present the frame. - m_swapChain!.Present(0, presentFlags); + m_swapChain!.Present(0, presentFlags).ThrowIfFailed(); MoveToNextFrame(); } @@ -209,8 +202,8 @@ public override void OnSizeChanged(int width, int height, bool minimized) } // Resize the swap chain to the desired dimensions. - DXGI_SWAP_CHAIN_DESC desc = m_swapChain!.GetDesc(); - m_swapChain.ResizeBuffers(FrameCount, (uint)width, (uint)height, desc.BufferDesc.Format, desc.Flags); + DXGI_SWAP_CHAIN_DESC1 desc = m_swapChain!.GetDesc1(); + m_swapChain.ResizeBuffers(FrameCount, (uint)width, (uint)height, desc.Format, desc.Flags); _ = m_swapChain.GetFullscreenState(out var fullscreenState); m_windowedMode = !fullscreenState; @@ -243,7 +236,7 @@ public override void OnUpdate() XMStoreFloat4x4(out m_sceneConstantBufferData.transform, transform.XMMatrixTranspose()); - int offset = m_frameIndex * Marshal.SizeOf(typeof(SceneConstantBuffer)); + int offset = m_frameIndex * Marshal.SizeOf(); Marshal.StructureToPtr(m_sceneConstantBufferData, m_pCbvDataBegin.Offset(offset), false); } @@ -257,8 +250,8 @@ private void LoadAssets() // Create a root signature consisting of a descriptor table with a single CBV. { - SafeNativeArray ranges = [new(D3D12_DESCRIPTOR_RANGE_TYPE.D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAGS.D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC)]; - SafeNativeArray rootParameters = [D3D12_ROOT_PARAMETER1.InitAsDescriptorTable(1, ranges, D3D12_SHADER_VISIBILITY.D3D12_SHADER_VISIBILITY_VERTEX)]; + D3D12_DESCRIPTOR_RANGE1[] ranges = [new(D3D12_DESCRIPTOR_RANGE_TYPE.D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAGS.D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC)]; + D3D12_ROOT_PARAMETER1[] rootParameters = [D3D12_ROOT_PARAMETER1.InitAsDescriptorTable(ranges, D3D12_SHADER_VISIBILITY.D3D12_SHADER_VISIBILITY_VERTEX, out var rp1)]; // Allow input layout and deny uneccessary access to certain pipeline stages. D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags = @@ -268,9 +261,9 @@ private void LoadAssets() D3D12_ROOT_SIGNATURE_FLAGS.D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAGS.D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS; - D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc = new(new D3D12_ROOT_SIGNATURE_DESC1(1, rootParameters, default, default, rootSignatureFlags)); + D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc = new(new D3D12_ROOT_SIGNATURE_DESC1(rootParameters, default, rootSignatureFlags, out var rsd)); - HRESULT.ThrowIfFailed(D3D12SerializeVersionedRootSignature(rootSignatureDesc, out var signature)); + D3D12SerializeVersionedRootSignature(rootSignatureDesc, out var signature).ThrowIfFailed(); m_sceneRootSignature = m_device!.CreateRootSignature(0, signature); NAME_D3D12_OBJECT(m_sceneRootSignature); } @@ -280,8 +273,8 @@ private void LoadAssets() // We don't modify the SRV in the post-processing command list after // SetGraphicsRootDescriptorTable is executed on the GPU so we can use the default // range behavior: D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE - SafeNativeArray ranges = [new(D3D12_DESCRIPTOR_RANGE_TYPE.D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0)]; - SafeNativeArray rootParameters = [D3D12_ROOT_PARAMETER1.InitAsDescriptorTable(1, ranges, D3D12_SHADER_VISIBILITY.D3D12_SHADER_VISIBILITY_PIXEL)]; + D3D12_DESCRIPTOR_RANGE1[] ranges = [new(D3D12_DESCRIPTOR_RANGE_TYPE.D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0)]; + D3D12_ROOT_PARAMETER1[] rootParameters = [D3D12_ROOT_PARAMETER1.InitAsDescriptorTable(ranges, D3D12_SHADER_VISIBILITY.D3D12_SHADER_VISIBILITY_PIXEL, out var rp1)]; // Allow input layout and pixel shader access and deny uneccessary access to certain pipeline stages. D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags = @@ -291,7 +284,7 @@ private void LoadAssets() D3D12_ROOT_SIGNATURE_FLAGS.D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS; // Create a sampler. - SafeCoTaskMemStruct sampler = new D3D12_STATIC_SAMPLER_DESC() + D3D12_STATIC_SAMPLER_DESC sampler = new() { Filter = D3D12_FILTER.D3D12_FILTER_MIN_MAG_MIP_LINEAR, AddressU = D3D12_TEXTURE_ADDRESS_MODE.D3D12_TEXTURE_ADDRESS_MODE_BORDER, @@ -309,9 +302,9 @@ private void LoadAssets() }; DumpVal(sampler, nameof(sampler)); - D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc = new(new D3D12_ROOT_SIGNATURE_DESC1(1, rootParameters, 1, sampler, rootSignatureFlags)); + D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc = new(new D3D12_ROOT_SIGNATURE_DESC1(rootParameters, [sampler], rootSignatureFlags, out var rsd)); - HRESULT.ThrowIfFailed(D3DX12SerializeVersionedRootSignature(rootSignatureDesc, featureData.HighestVersion, out var signature, out _)); + D3DX12SerializeVersionedRootSignature(rootSignatureDesc, featureData.HighestVersion, out var signature, out _).ThrowIfFailed(); m_postRootSignature = m_device!.CreateRootSignature(0, signature!); NAME_D3D12_OBJECT(m_postRootSignature); } @@ -325,18 +318,17 @@ private void LoadAssets() D3DCOMPILE compileFlags = 0; #endif - HRESULT.ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath("sceneShaders.hlsl"), IntPtr.Zero, null, "VSMain", "vs_5_0", compileFlags, 0, out var sceneVertexShader)); - HRESULT.ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath("sceneShaders.hlsl"), IntPtr.Zero, null, "PSMain", "ps_5_0", compileFlags, 0, out var scenePixelShader)); - - HRESULT.ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath("postShaders.hlsl"), IntPtr.Zero, null, "VSMain", "vs_5_0", compileFlags, 0, out var postVertexShader)); - HRESULT.ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath("postShaders.hlsl"), IntPtr.Zero, null, "PSMain", "ps_5_0", compileFlags, 0, out var postPixelShader)); + D3DCompileFromFile(GetAssetFullPath("sceneShaders.hlsl"), default, default, "VSMain", "vs_5_0", compileFlags, 0, out var pSceneVertexShaderData, out _).ThrowIfFailed(); + D3DCompileFromFile(GetAssetFullPath("sceneShaders.hlsl"), default, default, "PSMain", "ps_5_0", compileFlags, 0, out var pScenePixelShaderData, out _).ThrowIfFailed(); + D3DCompileFromFile(GetAssetFullPath("postShaders.hlsl"), default, default, "VSMain", "vs_5_0", compileFlags, 0, out var pPostVertexShaderData, out _).ThrowIfFailed(); + D3DCompileFromFile(GetAssetFullPath("postShaders.hlsl"), default, default, "PSMain", "ps_5_0", compileFlags, 0, out var pPostPixelShaderData, out _).ThrowIfFailed(); // Define the vertex input layouts. - SafeNativeArray inputElementDescs = [ + D3D12_INPUT_ELEMENT_DESC[] inputElementDescs = [ new("POSITION", DXGI_FORMAT.DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_INPUT_CLASSIFICATION.D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA), new("COLOR", DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT, 12, D3D12_INPUT_CLASSIFICATION.D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA) ]; - SafeNativeArray scaleInputElementDescs = [ + D3D12_INPUT_ELEMENT_DESC[] scaleInputElementDescs = [ new("POSITION", DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_INPUT_CLASSIFICATION.D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA), new("TEXCOORD", DXGI_FORMAT.DXGI_FORMAT_R32G32_FLOAT, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION.D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA) ]; @@ -344,26 +336,26 @@ private void LoadAssets() // Describe and create the graphics pipeline state objects (PSOs). D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = new() { - InputLayout = new(inputElementDescs.Count, inputElementDescs), + InputLayout = new(inputElementDescs, out var ied), pRootSignature = m_sceneRootSignature, - VS = new(sceneVertexShader), - PS = new(scenePixelShader), + VS = new(pSceneVertexShaderData), + PS = new(pScenePixelShaderData), RasterizerState = new(), BlendState = new(), - DepthStencilState = new() { DepthEnable = false, StencilEnable = false }, + DepthStencilState = new(depthEnable: false, stencilEnable: false), SampleMask = uint.MaxValue, PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE.D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, - SampleDesc = new() { Count = 1 } + SampleDesc = new(1, 0) }; psoDesc.SetRTVFormats([DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM]); DumpVal(psoDesc, nameof(psoDesc)); m_scenePipelineState = m_device!.CreateGraphicsPipelineState(psoDesc); NAME_D3D12_OBJECT(m_scenePipelineState); - psoDesc.InputLayout = new(scaleInputElementDescs.Count, scaleInputElementDescs); + psoDesc.InputLayout = new(scaleInputElementDescs, out ied); psoDesc.pRootSignature = m_postRootSignature; - psoDesc.VS = new(postVertexShader); - psoDesc.PS = new(postPixelShader); + psoDesc.VS = new(pPostVertexShaderData); + psoDesc.PS = new(pPostPixelShaderData); DumpVal(psoDesc, nameof(psoDesc)); m_postPipelineState = m_device!.CreateGraphicsPipelineState(psoDesc); @@ -407,7 +399,7 @@ private void LoadAssets() uint vertexBufferSize = quadVertices.Size; HRESULT.ThrowIfFailed(m_device!.CreateCommittedResource( - new D3D12_HEAP_PROPERTIES(D3D12_HEAP_TYPE.D3D12_HEAP_TYPE_DEFAULT), + new(D3D12_HEAP_TYPE.D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAGS.D3D12_HEAP_FLAG_NONE, D3D12_RESOURCE_DESC.Buffer(vertexBufferSize), D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_DEST, @@ -415,7 +407,7 @@ private void LoadAssets() out m_sceneVertexBuffer)); HRESULT.ThrowIfFailed(m_device!.CreateCommittedResource( - new D3D12_HEAP_PROPERTIES(D3D12_HEAP_TYPE.D3D12_HEAP_TYPE_UPLOAD), + new(D3D12_HEAP_TYPE.D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAGS.D3D12_HEAP_FLAG_NONE, D3D12_RESOURCE_DESC.Buffer(vertexBufferSize), D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_GENERIC_READ, @@ -432,14 +424,13 @@ private void LoadAssets() sceneVertexBufferUpload!.Unmap(0, default); commandList!.CopyBufferRegion(m_sceneVertexBuffer!, 0, sceneVertexBufferUpload, 0, vertexBufferSize); - commandList.ResourceBarrier(1, [D3D12_RESOURCE_BARRIER.CreateTransition(m_sceneVertexBuffer!, - D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)]); + commandList.ResourceBarrier([D3D12_RESOURCE_BARRIER.CreateTransition(m_sceneVertexBuffer!, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)]); // Initialize the vertex buffer views. m_sceneVertexBufferView = new() { BufferLocation = m_sceneVertexBuffer!.GetGPUVirtualAddress(), - StrideInBytes = (uint)Marshal.SizeOf(typeof(SceneVertex)), + StrideInBytes = (uint)Marshal.SizeOf(), SizeInBytes = vertexBufferSize }; } @@ -480,50 +471,46 @@ private void LoadAssets() postVertexBufferUpload!.Unmap(0, default); commandList.CopyBufferRegion(m_postVertexBuffer!, 0, postVertexBufferUpload, 0, vertexBufferSize); - commandList.ResourceBarrier(1, [D3D12_RESOURCE_BARRIER.CreateTransition(m_postVertexBuffer!, - D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)]); + commandList.ResourceBarrier([D3D12_RESOURCE_BARRIER.CreateTransition(m_postVertexBuffer!, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)]); // Initialize the vertex buffer views. m_postVertexBufferView = new() { BufferLocation = m_postVertexBuffer!.GetGPUVirtualAddress(), - StrideInBytes = (uint)Marshal.SizeOf(typeof(PostVertex)), + StrideInBytes = (uint)Marshal.SizeOf(), SizeInBytes = vertexBufferSize }; } // Create the constant buffer. { - var constantBufferByteSize = (uint)Marshal.SizeOf(typeof(SceneConstantBuffer)); + var sceneConstantBufferSize = (uint)Marshal.SizeOf(); HRESULT.ThrowIfFailed(m_device!.CreateCommittedResource( new(D3D12_HEAP_TYPE.D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAGS.D3D12_HEAP_FLAG_NONE, - D3D12_RESOURCE_DESC.Buffer((ulong)constantBufferByteSize * FrameCount), + D3D12_RESOURCE_DESC.Buffer((ulong)sceneConstantBufferSize * FrameCount), D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_GENERIC_READ, default, out m_sceneConstantBuffer)); NAME_D3D12_OBJECT(m_sceneConstantBuffer!); - unsafe + // Describe and create constant buffer views. + D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = new() { - // Describe and create constant buffer views. - D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = new() - { - BufferLocation = m_sceneConstantBuffer!.GetGPUVirtualAddress(), - SizeInBytes = constantBufferByteSize - }; + BufferLocation = m_sceneConstantBuffer!.GetGPUVirtualAddress(), + SizeInBytes = sceneConstantBufferSize + }; - D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle = new(m_cbvSrvHeap!.GetCPUDescriptorHandleForHeapStart(), 1, m_cbvSrvDescriptorSize); + D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle = new(m_cbvSrvHeap!.GetCPUDescriptorHandleForHeapStart(), 1, m_cbvSrvDescriptorSize); - for (uint n = 0; n < FrameCount; n++) - { - m_device!.CreateConstantBufferView(cbvDesc, cpuHandle); + for (uint n = 0; n < FrameCount; n++) + { + m_device!.CreateConstantBufferView(cbvDesc, cpuHandle); - cbvDesc.BufferLocation += constantBufferByteSize; - cpuHandle.Offset((int)m_cbvSrvDescriptorSize); - } + cbvDesc.BufferLocation += sceneConstantBufferSize; + cpuHandle.Offset((int)m_cbvSrvDescriptorSize); } // Map and initialize the constant buffer. We don't unmap this until the @@ -537,7 +524,7 @@ private void LoadAssets() // the default heap. HRESULT.ThrowIfFailed(commandList.Close()); ID3D12CommandList[] ppCommandLists = [commandList]; - m_commandQueue!.ExecuteCommandLists(ppCommandLists.Length, ppCommandLists); + m_commandQueue!.ExecuteCommandLists(ppCommandLists); // Create synchronization objects and wait until assets have been uploaded to the GPU. { @@ -611,7 +598,7 @@ private void LoadPipeline() Format = DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM, BufferUsage = DXGI_USAGE.DXGI_USAGE_RENDER_TARGET_OUTPUT, SwapEffect = DXGI_SWAP_EFFECT.DXGI_SWAP_EFFECT_FLIP_DISCARD, - SampleDesc = new() { Count = 1 }, + SampleDesc = new(1, 0), }; // Swap chain needs the queue so that it can force a flush on it. @@ -702,12 +689,12 @@ private void LoadSizeDependentResources() // Create frame resources. { - m_rtvHeap!.GetCPUDescriptorHandleForHeapStart(out var rtvHandle); + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = m_rtvHeap!.GetCPUDescriptorHandleForHeapStart(); // Create a RTV for each frame. for (uint n = 0; n < FrameCount; n++) { - m_renderTargets![n] = m_swapChain!.GetBuffer(n); + m_swapChain!.GetBuffer(n, out m_renderTargets![n]).ThrowIfFailed(); m_device!.CreateRenderTargetView(m_renderTargets[n], default, rtvHandle); rtvHandle.Offset(1, m_rtvDescriptorSize); @@ -745,15 +732,13 @@ private void MoveToNextFrame() // Fill the command list with all the render commands and dependent state. private void PopulateCommandLists() { - // Command list allocators can only be reset when the associated - // command lists have finished execution on the GPU; apps should use + // Command list allocators can only be reset when the associated command lists have finished execution on the GPU; apps should use // fences to determine GPU execution progress. HRESULT.ThrowIfFailed(m_sceneCommandAllocators[m_frameIndex].Reset()); HRESULT.ThrowIfFailed(m_postCommandAllocators[m_frameIndex].Reset()); - // However, when ExecuteCommandList() is called on a particular command - // list, that command list can then be reset at any time and must be before - // re-recording. + // However, when ExecuteCommandList() is called on a particular command list, that command list can then be reset at any time and + // must be before re-recording. HRESULT.ThrowIfFailed(m_sceneCommandList!.Reset(m_sceneCommandAllocators[m_frameIndex], m_scenePipelineState)); HRESULT.ThrowIfFailed(m_postCommandList!.Reset(m_postCommandAllocators[m_frameIndex], m_postPipelineState)); @@ -762,26 +747,24 @@ private void PopulateCommandLists() // Set necessary state. m_sceneCommandList.SetGraphicsRootSignature(m_sceneRootSignature); - m_sceneCommandList.SetDescriptorHeaps(1, [m_cbvSrvHeap!]); + m_sceneCommandList.SetDescriptorHeaps([m_cbvSrvHeap!]); D3D12_GPU_DESCRIPTOR_HANDLE cbvHandle = new(m_cbvSrvHeap!.GetGPUDescriptorHandleForHeapStart(), m_frameIndex + 1, m_cbvSrvDescriptorSize); m_sceneCommandList.SetGraphicsRootDescriptorTable(0, cbvHandle); m_sceneCommandList.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY.D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - m_sceneCommandList.RSSetViewports(1, [m_sceneViewport]); - m_sceneCommandList.RSSetScissorRects(1, [m_sceneScissorRect]); + m_sceneCommandList.RSSetViewports([m_sceneViewport]); + m_sceneCommandList.RSSetScissorRects([m_sceneScissorRect]); D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = new(m_rtvHeap!.GetCPUDescriptorHandleForHeapStart(), FrameCount, m_rtvDescriptorSize); - m_sceneCommandList.OMSetRenderTargets(1, [rtvHandle], false, default); + m_sceneCommandList.OMSetRenderTargets([rtvHandle], false); // Record commands. - m_sceneCommandList.ClearRenderTargetView(rtvHandle, ClearColor, 0, default); + m_sceneCommandList.ClearRenderTargetView(rtvHandle, ClearColor); m_sceneCommandList.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY.D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - m_sceneCommandList.IASetVertexBuffers(0, 1, [m_sceneVertexBufferView]); + m_sceneCommandList.IASetVertexBuffers(0, [m_sceneVertexBufferView]); - //using (new PIXEvent(m_sceneCommandList, "Draw a thin rectangle")) - PIXEvent.PIXBeginEvent(m_sceneCommandList, 0, "Draw a thin rectangle"); - m_sceneCommandList.DrawInstanced(4, 1, 0, 0); - PIXEvent.PIXEndEvent(m_sceneCommandList); + using (new PIXEvent(m_sceneCommandList, "Draw a thin rectangle")) + m_sceneCommandList.DrawInstanced(4, 1, 0, 0); } HRESULT.ThrowIfFailed(m_sceneCommandList.Close()); @@ -791,42 +774,39 @@ private void PopulateCommandLists() // Set necessary state. m_postCommandList.SetGraphicsRootSignature(m_postRootSignature); - m_postCommandList.SetDescriptorHeaps(1, [m_cbvSrvHeap!]); + m_postCommandList.SetDescriptorHeaps([m_cbvSrvHeap!]); - // Indicate that the back buffer will be used as a render target and the - // intermediate render target will be used as a SRV. + // Indicate that the back buffer will be used as a render target and the intermediate render target will be used as a SRV. D3D12_RESOURCE_BARRIER[] barriers = [ D3D12_RESOURCE_BARRIER.CreateTransition(m_renderTargets![m_frameIndex]!, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_RENDER_TARGET), D3D12_RESOURCE_BARRIER.CreateTransition(m_intermediateRenderTarget!, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) ]; - m_postCommandList.ResourceBarrier(barriers.Length, barriers); + m_postCommandList.ResourceBarrier(barriers); m_postCommandList.SetGraphicsRootDescriptorTable(0, m_cbvSrvHeap!.GetGPUDescriptorHandleForHeapStart()); m_postCommandList.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY.D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - m_postCommandList.RSSetViewports(1, [m_postViewport]); - m_postCommandList.RSSetScissorRects(1, [m_postScissorRect]); + m_postCommandList.RSSetViewports([m_postViewport]); + m_postCommandList.RSSetScissorRects([m_postScissorRect]); D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = new(m_rtvHeap!.GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_rtvDescriptorSize); - m_postCommandList.OMSetRenderTargets(1, [rtvHandle], false, default); + m_postCommandList.OMSetRenderTargets([rtvHandle], false); // Record commands. - m_postCommandList.ClearRenderTargetView(rtvHandle, LetterboxColor, 0, default); + m_postCommandList.ClearRenderTargetView(rtvHandle, LetterboxColor); m_postCommandList.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY.D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - m_postCommandList.IASetVertexBuffers(0, 1, [m_postVertexBufferView]); + m_postCommandList.IASetVertexBuffers(0, [m_postVertexBufferView]); - //using (new PIXEvent(m_postCommandList, "Draw texture to screen.")) - PIXEvent.PIXBeginEvent(m_postCommandList, 0, "Draw texture to screen."); - m_postCommandList.DrawInstanced(4, 1, 0, 0); - PIXEvent.PIXEndEvent(m_postCommandList); + using (new PIXEvent(m_postCommandList, "Draw texture to screen.")) + m_postCommandList.DrawInstanced(4, 1, 0, 0); // Revert resource states back to original values. - barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_RENDER_TARGET; - barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_PRESENT; - barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; - barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_RENDER_TARGET; + barriers = [ + D3D12_RESOURCE_BARRIER.CreateTransition(m_renderTargets![m_frameIndex]!, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_PRESENT), + D3D12_RESOURCE_BARRIER.CreateTransition(m_intermediateRenderTarget!, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_RENDER_TARGET) + ]; - m_postCommandList.ResourceBarrier(barriers.Length, barriers); + m_postCommandList.ResourceBarrier(barriers); } HRESULT.ThrowIfFailed(m_postCommandList.Close()); @@ -836,6 +816,7 @@ private void PopulateCommandLists() private void ReleaseD3DResources() { m_fence = null; + m_renderTargets?.Fill(null); m_renderTargets = null; m_commandQueue = null; m_swapChain = null; @@ -847,14 +828,8 @@ private void ReleaseD3DResources() private void RestoreD3DResources() { // Give GPU a chance to finish its execution in progress. - try - { - WaitForGpu(); - } - catch - { - // Do nothing, currently attached adapter is unresponsive. - } + try { WaitForGpu(); } + catch { } // Do nothing, currently attached adapter is unresponsive. ReleaseD3DResources(); OnInit(); } @@ -939,4 +914,13 @@ private struct Vertex(float r, float g, float b, float a, float x, float y, floa public D3DCOLORVALUE color = new(r, b, g, a); public D2D_VECTOR_3F position = new(x, y, z); } +} + +internal static class Ext +{ + public static void Fill(this IList l, T? value = default) + { + for (int i = 0; i < l.Count; i++) + l[i] = value!; + } } \ No newline at end of file diff --git a/DirectX-Graphics-Samples/D3D12Fullscreen/D3D12Fullscreen.png b/DirectX-Graphics-Samples/D3D12Fullscreen/D3D12Fullscreen.png new file mode 100644 index 00000000..d82b961c Binary files /dev/null and b/DirectX-Graphics-Samples/D3D12Fullscreen/D3D12Fullscreen.png differ diff --git a/DirectX-Graphics-Samples/D3D12HelloWorld/HelloConstBuffers/D3D12HelloConstBuffers.cs b/DirectX-Graphics-Samples/D3D12HelloWorld/HelloConstBuffers/D3D12HelloConstBuffers.cs index 0c84cc77..e7ed81e4 100644 --- a/DirectX-Graphics-Samples/D3D12HelloWorld/HelloConstBuffers/D3D12HelloConstBuffers.cs +++ b/DirectX-Graphics-Samples/D3D12HelloWorld/HelloConstBuffers/D3D12HelloConstBuffers.cs @@ -240,13 +240,13 @@ private void LoadAssets() // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer.GetGPUVirtualAddress(); - m_vertexBufferView.StrideInBytes = (uint)Marshal.SizeOf(typeof(Vertex)); + m_vertexBufferView.StrideInBytes = (uint)Marshal.SizeOf(); m_vertexBufferView.SizeInBytes = vertexBufferSize; } // Create the constant buffer. { - uint constantBufferSize = (uint)Marshal.SizeOf(typeof(SceneConstantBuffer)); // CB size is required to be 256-byte aligned. + uint constantBufferSize = (uint)Marshal.SizeOf(); // CB size is required to be 256-byte aligned. HRESULT.ThrowIfFailed(m_device!.CreateCommittedResource( new D3D12_HEAP_PROPERTIES(D3D12_HEAP_TYPE.D3D12_HEAP_TYPE_UPLOAD), diff --git a/DirectX-Graphics-Samples/D3D12HelloWorld/HelloGenericPrograms/D3D12HelloGenericPrograms.cs b/DirectX-Graphics-Samples/D3D12HelloWorld/HelloGenericPrograms/D3D12HelloGenericPrograms.cs index c9649988..11926fa2 100644 --- a/DirectX-Graphics-Samples/D3D12HelloWorld/HelloGenericPrograms/D3D12HelloGenericPrograms.cs +++ b/DirectX-Graphics-Samples/D3D12HelloWorld/HelloGenericPrograms/D3D12HelloGenericPrograms.cs @@ -267,7 +267,7 @@ private void LoadAssets() new() { position = new(-0.25f, -0.25f * m_aspectRatio, 0.0f), color = new(0.0f, 0.0f, 1.0f, 1.0f) } ]; - uint vertexBufferSize = (uint)(Marshal.SizeOf(typeof(Vertex)) * triangleVertices.Length); + uint vertexBufferSize = (uint)(Marshal.SizeOf() * triangleVertices.Length); // Note: using upload heaps to transfer static data like vert buffers is not recommended. Every time the GPU needs it, the // upload heap will be marshalled over. Please read up on Default Heap usage. An upload heap is used here for code simplicity @@ -282,7 +282,7 @@ private void LoadAssets() // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer.GetGPUVirtualAddress(); - m_vertexBufferView.StrideInBytes = (uint)Marshal.SizeOf(typeof(Vertex)); + m_vertexBufferView.StrideInBytes = (uint)Marshal.SizeOf(); m_vertexBufferView.SizeInBytes = vertexBufferSize; } diff --git a/DirectX-Graphics-Samples/D3D12HelloWorld/HelloGenericPrograms/DXSample.cs b/DirectX-Graphics-Samples/D3D12HelloWorld/HelloGenericPrograms/DXSample.cs index 76a28193..35277cc0 100644 --- a/DirectX-Graphics-Samples/D3D12HelloWorld/HelloGenericPrograms/DXSample.cs +++ b/DirectX-Graphics-Samples/D3D12HelloWorld/HelloGenericPrograms/DXSample.cs @@ -106,45 +106,31 @@ protected internal static ID3DBlob CompileShader(string filename, in D3D_SHADER_ protected internal static void NAME_D3D12_OBJECT_INDEXED(IReadOnlyList obj, SizeT idx, [CallerArgumentExpression(nameof(obj))] string? objName = null) where T : ID3D12Object => SetNameIndexed(obj[idx], objName, idx); - protected internal static HRESULT ReadDataFromDDSFile(string filename, out byte[] data, ref uint offset, ref uint size) + protected internal static HRESULT ReadDataFromDDSFile(string filename, out ID3DBlob data, ref uint offset, ref uint size) { if (ReadDataFromFile(filename, out data).Failed) - { return HRESULT.E_FAIL; - } // DDS files always start with the same magic number. const uint DDS_MAGIC = 0x20534444; - uint magicNumber = BitConverter.ToUInt32(data); + uint magicNumber = data.GetBufferPointer().ToStructure(); if (magicNumber != DDS_MAGIC) - { return HRESULT.E_FAIL; - } unsafe { - fixed (byte* pData = data) - { - var ddsHeader = (DDS_HEADER*)(pData + sizeof(uint)); - if (ddsHeader->size != sizeof(DDS_HEADER) || ddsHeader->ddsPixelFormat.size != sizeof(DDS_PIXELFORMAT)) - { - return HRESULT.E_FAIL; - } - - nint ddsDataOffset = sizeof(uint) + sizeof(DDS_HEADER); - offset = (uint)ddsDataOffset; - size -= offset; - } + var ddsHeader = (DDS_HEADER*)(data.GetBufferPointer() + sizeof(uint)); + if (ddsHeader->size != sizeof(DDS_HEADER) || ddsHeader->ddsPixelFormat.size != sizeof(DDS_PIXELFORMAT)) + return HRESULT.E_FAIL; + + size -= (uint)(sizeof(uint) + sizeof(DDS_HEADER)); } return HRESULT.S_OK; } - protected internal static HRESULT ReadDataFromFile(string filename, out byte[] data) - { - data = System.IO.File.ReadAllBytes(filename); - return HRESULT.S_OK; - } + protected internal static HRESULT ReadDataFromFile(string filename, out ID3DBlob data) => + D3DCompiler.D3DReadFileToBlob(filename, out data); [Conditional("DEBUG")] protected internal static void SetName(ID3D12Object pObject, string? name) => pObject.SetName(name ?? ""); diff --git a/DirectX-Graphics-Samples/D3D12HelloWorld/HelloTexture/D3D12HelloTexture.cs b/DirectX-Graphics-Samples/D3D12HelloWorld/HelloTexture/D3D12HelloTexture.cs index 65e03c72..70967566 100644 --- a/DirectX-Graphics-Samples/D3D12HelloWorld/HelloTexture/D3D12HelloTexture.cs +++ b/DirectX-Graphics-Samples/D3D12HelloWorld/HelloTexture/D3D12HelloTexture.cs @@ -243,7 +243,7 @@ void LoadAssets() m_vertexBufferView = new() { BufferLocation = m_vertexBuffer.GetGPUVirtualAddress(), - StrideInBytes = (uint)Marshal.SizeOf(typeof(Vertex)), + StrideInBytes = (uint)Marshal.SizeOf(), SizeInBytes = vertexBufferSize }; } diff --git a/DirectX-Graphics-Samples/D3D12HelloWorld/HelloTriangle/D3D12HelloTriangle.cs b/DirectX-Graphics-Samples/D3D12HelloWorld/HelloTriangle/D3D12HelloTriangle.cs index d0631cbd..b89387d2 100644 --- a/DirectX-Graphics-Samples/D3D12HelloWorld/HelloTriangle/D3D12HelloTriangle.cs +++ b/DirectX-Graphics-Samples/D3D12HelloWorld/HelloTriangle/D3D12HelloTriangle.cs @@ -139,7 +139,7 @@ private void LoadAssets() // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer.GetGPUVirtualAddress(); - m_vertexBufferView.StrideInBytes = (uint)Marshal.SizeOf(typeof(Vertex)); + m_vertexBufferView.StrideInBytes = (uint)Marshal.SizeOf(); m_vertexBufferView.SizeInBytes = vertexBufferSize; } diff --git a/DirectX-Graphics-Samples/D3D12nBodyGravity/D3D12nBodyGravity.cs b/DirectX-Graphics-Samples/D3D12nBodyGravity/D3D12nBodyGravity.cs index 5e0aea70..fed66d09 100644 --- a/DirectX-Graphics-Samples/D3D12nBodyGravity/D3D12nBodyGravity.cs +++ b/DirectX-Graphics-Samples/D3D12nBodyGravity/D3D12nBodyGravity.cs @@ -190,7 +190,7 @@ public override void OnUpdate() if (m_pConstantBufferGSData != IntPtr.Zero) { - IntPtr destination = m_pConstantBufferGSData.Offset(Marshal.SizeOf(typeof(ConstantBufferGS)) * m_frameIndex); + IntPtr destination = m_pConstantBufferGSData.Offset(Marshal.SizeOf() * m_frameIndex); _ = destination.Write(constantBufferGS); } } @@ -664,7 +664,7 @@ private void LoadAssets() // Create the compute shader's constant buffer. { - uint bufferSize = (uint)Marshal.SizeOf(typeof(ConstantBufferCS)); + uint bufferSize = (uint)Marshal.SizeOf(); if (m_bIsEnhancedBarriersEnabled) { @@ -742,7 +742,7 @@ private void LoadAssets() // Create the geometry shader's constant buffer. { - uint constantBufferGSSize = (uint)Marshal.SizeOf(typeof(ConstantBufferGS)) * FrameCount; + uint constantBufferGSSize = (uint)Marshal.SizeOf() * FrameCount; if (m_bIsEnhancedBarriersEnabled) { @@ -1196,16 +1196,4 @@ private class ThreadData public D3D12nBodyGravity? pContext; public int threadIndex; } -} - -internal static class Ext -{ - public static HRESULT Map(this ID3D12Resource resource, uint subresource, [In, Optional] D3D12_RANGE? readRange, out IntPtr dataPtr) - { - unsafe - { - fixed (void* pData = &dataPtr) - return resource.Map(subresource, readRange, (IntPtr)pData); - } - } } \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index 0f9aa801..3fa263d8 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,14 +3,14 @@ true true $(NoWarn);NU1507 - 5.0.3 + 5.0.5 - + @@ -18,6 +18,8 @@ + + diff --git a/HangulDecomposition/HangulDecomposition.cs b/HangulDecomposition/HangulDecomposition.cs index 46aff030..e324da01 100644 --- a/HangulDecomposition/HangulDecomposition.cs +++ b/HangulDecomposition/HangulDecomposition.cs @@ -11,7 +11,7 @@ internal static void Main() { // create Hangul Decomposition Transliteration service. using var pGuid = new PinnedObject(ELS_GUID_TRANSLITERATION_HANGUL_DECOMPOSITION); - MAPPING_ENUM_OPTIONS enumOptions = new() { Size = Marshal.SizeOf(typeof(MAPPING_ENUM_OPTIONS)), pGuid = (IntPtr)pGuid }; + MAPPING_ENUM_OPTIONS enumOptions = new() { Size = Marshal.SizeOf(), pGuid = (IntPtr)pGuid }; int testCount = 1; if (MappingGetServices(enumOptions, out var mappingServiceInfo).Succeeded) diff --git a/PortableDeviceCOM/ContentTransfer.cs b/PortableDeviceCOM/ContentTransfer.cs index 65937c16..40670130 100644 --- a/PortableDeviceCOM/ContentTransfer.cs +++ b/PortableDeviceCOM/ContentTransfer.cs @@ -278,7 +278,7 @@ static void TransferContentToDevice([In] IPortableDevice device, in Guid content SafeLPTSTR defFileExt = new(defaultFileExtension); OPENFILENAME openFileNameInfo = new() { - lStructSize = (uint)Marshal.SizeOf(typeof(OPENFILENAME)), + lStructSize = (uint)Marshal.SizeOf(), hwndOwner = default, lpstrFile = filePath, nMaxFile = (uint)filePath.Capacity, @@ -349,7 +349,7 @@ static void CreateContactPhotoResourceOnDevice([In] IPortableDevice device) SafeLPTSTR defFileExt = new("JPG"); OPENFILENAME openFileNameInfo = new() { - lStructSize = (uint)Marshal.SizeOf(typeof(OPENFILENAME)), + lStructSize = (uint)Marshal.SizeOf(), hwndOwner = default, lpstrFile = filePath, nMaxFile = (uint)filePath.Capacity, @@ -528,7 +528,7 @@ static void UpdateContentOnDevice([In] IPortableDevice device, in Guid contentTy SafeLPTSTR defFileExt = new(defaultFileExtension); OPENFILENAME openFileNameInfo = new() { - lStructSize = (uint)Marshal.SizeOf(typeof(OPENFILENAME)), + lStructSize = (uint)Marshal.SizeOf(), hwndOwner = default, lpstrFile = filePath, nMaxFile = (uint)filePath.Capacity, diff --git a/PowerSettingRegisterNotification/PowerSettingRegisterNotificationSample.cs b/PowerSettingRegisterNotification/PowerSettingRegisterNotificationSample.cs index f14646cf..17512e69 100644 --- a/PowerSettingRegisterNotification/PowerSettingRegisterNotificationSample.cs +++ b/PowerSettingRegisterNotification/PowerSettingRegisterNotificationSample.cs @@ -83,7 +83,7 @@ Win32Error EnergySaverPowerSettingCallback([In, Optional] IntPtr Context, uint T // // Check the data size is expected // - if (settingId != GUID_ENERGY_SAVER_STATUS || powerSetting.DataLength != Marshal.SizeOf(typeof(ENERGY_SAVER_STATUS))) + if (settingId != GUID_ENERGY_SAVER_STATUS || powerSetting.DataLength != Marshal.SizeOf()) { return Win32Error.ERROR_INVALID_PARAMETER; } diff --git a/Sampler/App.config b/Sampler/App.config new file mode 100644 index 00000000..d69b9952 --- /dev/null +++ b/Sampler/App.config @@ -0,0 +1,21 @@ + + + + +
+ + + + + + + + + %USERPROFILE%\Documents\GitHubRepos\WinClassicSamplesCS + + + Sampler + + + + \ No newline at end of file diff --git a/Sampler/AssemblyElements.cs b/Sampler/AssemblyElements.cs new file mode 100644 index 00000000..a6706356 --- /dev/null +++ b/Sampler/AssemblyElements.cs @@ -0,0 +1,172 @@ +namespace Sampler; + +public enum ElementType +{ + Assembly = 1, + Class, + Delegate, + Enum, + Field, + Interface, + Method, + Namespace, + Property, + Struct, +} + +internal interface IAsyncRefresh +{ + System.Threading.Tasks.Task RefreshAsync(CancellationToken cancellationToken, IProgress? progress); +} + +internal interface IElementInfo +{ + public IEnumerable Children => []; + public ElementType ElementType { get; } + public string? ImageUrl => null; + public string Name { get; } +} + +internal class AssemblyInfo(System.Reflection.Assembly assembly) : IElementInfo, IAsyncRefresh +{ + private readonly System.Reflection.Assembly assembly = assembly; + private readonly List namespaces = []; + public IEnumerable Children => namespaces; + public ElementType ElementType => ElementType.Assembly; + public string Name => assembly.GetName().Name ?? throw new InvalidOperationException("Assembly name cannot be null."); + + public async System.Threading.Tasks.Task RefreshAsync(CancellationToken cancellationToken, IProgress? progress) => await RefreshAsync( + () => assembly.GetExportedTypes(), + async (types, getChunk, progress) => + { + // Fill namespaces list with the namespaces found in the assembly showing progress starting at getChuck and ending at 100. + int totalTypes = types?.Length ?? 0; + HashSet seenNamespaces = []; + for (int i = 0; i < totalTypes; i++) + { + cancellationToken.ThrowIfCancellationRequested(); + var type = types![i]; + var ns = type.Namespace ?? string.Empty; + if (seenNamespaces.Add(ns)) + namespaces.Add(new NamespaceInfo(ns, assembly)); + progress?.Report(getChunk + ((i + 1) * (100 - getChunk) / totalTypes)); + } + }, + progress: progress, + cancellationToken: cancellationToken); + + internal static async System.Threading.Tasks.Task RefreshAsync(Func? blockingMethod, Action?> asyncProcessor, + int getChunk = 30, int fakeProgressDelay = 500, IProgress? progress = null, CancellationToken cancellationToken = default) + { + int percent = 0; + progress?.Report(percent); + T? result = default; + if (blockingMethod is not null) + { + using (Timer timer = new(_ => { if (percent < getChunk) progress?.Report(percent += 5); }, null, 0, fakeProgressDelay)) + result = await System.Threading.Tasks.Task.Run(blockingMethod, cancellationToken); + progress?.Report(getChunk); + } + else + getChunk = 0; + + // Call asyncProcessor with the result of blockingMethod, if asyncProcessor is not null. + await System.Threading.Tasks.Task.Run(() => asyncProcessor(result, getChunk, progress), cancellationToken); + progress?.Report(100); + } +} + +internal class ClassInfo(Type type) : TypeInfo(type) +{ + public override ElementType ElementType => ElementType.Class; + public override string? ImageUrl => "class.png"; +} + +internal class DelegateInfo(Type type) : TypeInfo(type) +{ + public override ElementType ElementType => ElementType.Delegate; + public override string? ImageUrl => "delegate.png"; +} + +internal class EnumInfo(Type type) : TypeInfo(type) +{ + public override ElementType ElementType => ElementType.Enum; + public override string? ImageUrl => "enum.png"; +} + +internal class FieldInfo(System.Reflection.FieldInfo field) : IElementInfo +{ + public ElementType ElementType => ElementType.Field; + public System.Reflection.FieldInfo Field => @field; + public string Name => @field.Name; +} + +internal class InterfaceInfo(Type type) : TypeInfo(type) +{ + public override ElementType ElementType => ElementType.Interface; + public override string? ImageUrl => "interface.png"; +} + +internal class MethodInfo(System.Reflection.MethodInfo method) : IElementInfo +{ + public ElementType ElementType => ElementType.Method; + public System.Reflection.MethodInfo Method => method; + public string Name => method.Name; +} + +internal class NamespaceInfo(string name, System.Reflection.Assembly assembly) : IElementInfo +{ + //private readonly System.Reflection.Assembly assembly = assembly; + private readonly Lazy> types = new(() => [.. assembly.GetExportedTypes().Where(t => t.Namespace == name).Select(TypeInfo.MakeType)]); + + public IEnumerable Children => types.Value; + public ElementType ElementType => ElementType.Namespace; + public string Name => name; +} + +internal class StructInfo(Type type) : TypeInfo(type) +{ + public override ElementType ElementType => ElementType.Struct; + public override string? ImageUrl => "struct.png"; +} + +internal abstract class TypeInfo(Type type) : IElementInfo +{ + private readonly Lazy> delegates = new(() => [.. type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Where(t => typeof(Delegate).IsAssignableFrom(t.FieldType)).Select(t => new DelegateInfo(t.FieldType))]); + private readonly Lazy> fields = new(() => [.. type.GetFields(System.Reflection.BindingFlags.Public).Select(f => new FieldInfo(f))]); + private readonly Lazy> methods = new(() => [.. type.GetMethods(System.Reflection.BindingFlags.Public).Select(m => new MethodInfo(m))]); + private readonly Lazy> properties = new(() => [.. type.GetProperties(System.Reflection.BindingFlags.Public).Select(p => new PropertyInfo(p))]); + private readonly Lazy> staticMethods = new(() => [.. type.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).Select(m => new MethodInfo(m))]); + private readonly Lazy> types = new(() => [.. type.GetNestedTypes(System.Reflection.BindingFlags.Public).Select(MakeType)]); + + public virtual IEnumerable Children => types.Value; + public abstract ElementType ElementType { get; } + public abstract string? ImageUrl { get; } + public virtual string Name => type.Name; + public Type Type => type; + protected virtual IEnumerable Delegates => delegates.Value; + protected virtual IEnumerable Fields => fields.Value; + protected virtual IEnumerable Methods => methods.Value; + protected virtual IEnumerable Properties => properties.Value; + protected virtual IEnumerable StaticMethods => staticMethods.Value; + + internal static TypeInfo MakeType(Type type) + { + if (type.IsInterface) + return new InterfaceInfo(type); + else if (typeof(Delegate).IsAssignableFrom(type)) + return new DelegateInfo(type); + else if (type.IsClass) + return new ClassInfo(type); + else if (type.IsEnum) + return new EnumInfo(type); + else return type.IsValueType ? (TypeInfo)new StructInfo(type) : throw new NotSupportedException($"Type {type.FullName} is not supported."); + } +} + +internal class PropertyInfo(System.Reflection.PropertyInfo property) : IElementInfo +{ + public ElementType ElementType => ElementType.Property; + public string Name => property.Name; + public System.Reflection.PropertyInfo Property => property; +} \ No newline at end of file diff --git a/Sampler/CodeIndexBuilder.cs b/Sampler/CodeIndexBuilder.cs new file mode 100644 index 00000000..059ceed4 --- /dev/null +++ b/Sampler/CodeIndexBuilder.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Sampler; + +/// +/// Given a list of assemblies, this class will build an index of all the public types and members in those assemblies, so that we can +/// quickly look up information about them later. +/// +internal static class CodeIndexBuilder +{ + //public static CodeIndex BuildIndex(IEnumerable assemblies) + //{ + // var index = new CodeIndex(); + // foreach (var assembly in assemblies) + // { + // foreach (var type in assembly.GetExportedTypes()) + // { + // index.Types[type.FullName] = type; + // foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) + // { + // index.Members[$"{type.FullName}.{member.Name}"] = member; + // } + // } + // } + // return index; + //} +} diff --git a/Sampler/Form1.Designer.cs b/Sampler/Form1.Designer.cs new file mode 100644 index 00000000..7b51f612 --- /dev/null +++ b/Sampler/Form1.Designer.cs @@ -0,0 +1,164 @@ +namespace Sampler +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.projectView = new System.Windows.Forms.TreeView(); + this.treeViewImageList = new System.Windows.Forms.ImageList(this.components); + this.splitter1 = new System.Windows.Forms.Splitter(); + this.treeLoader = new System.ComponentModel.BackgroundWorker(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.explorerBrowser = new Vanara.Windows.Forms.ExplorerBrowser(); + this.titleLabel = new System.Windows.Forms.Label(); + this.runButton = new System.Windows.Forms.Button(); + this.tableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // projectView + // + this.projectView.Dock = System.Windows.Forms.DockStyle.Left; + this.projectView.ImageIndex = 0; + this.projectView.ImageList = this.treeViewImageList; + this.projectView.Location = new System.Drawing.Point(0, 0); + this.projectView.Name = "projectView"; + this.projectView.SelectedImageIndex = 0; + this.projectView.Size = new System.Drawing.Size(266, 592); + this.projectView.TabIndex = 0; + this.projectView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.projectView_AfterSelect); + // + // treeViewImageList + // + this.treeViewImageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; + this.treeViewImageList.ImageSize = new System.Drawing.Size(16, 16); + this.treeViewImageList.TransparentColor = System.Drawing.Color.Transparent; + // + // splitter1 + // + this.splitter1.Location = new System.Drawing.Point(266, 0); + this.splitter1.Name = "splitter1"; + this.splitter1.Size = new System.Drawing.Size(3, 592); + this.splitter1.TabIndex = 1; + this.splitter1.TabStop = false; + // + // treeLoader + // + this.treeLoader.DoWork += new System.ComponentModel.DoWorkEventHandler(this.treeLoader_DoWork); + this.treeLoader.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.treeLoader_RunWorkerCompleted); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.Controls.Add(this.explorerBrowser, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.titleLabel, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.runButton, 1, 0); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(269, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(622, 592); + this.tableLayoutPanel1.TabIndex = 5; + // + // explorerBrowser + // + this.tableLayoutPanel1.SetColumnSpan(this.explorerBrowser, 2); + this.explorerBrowser.ContentFlags = ((Vanara.Windows.Forms.ExplorerBrowserContentSectionOptions)((((Vanara.Windows.Forms.ExplorerBrowserContentSectionOptions.SingleSelection | Vanara.Windows.Forms.ExplorerBrowserContentSectionOptions.NoSubfolders) + | Vanara.Windows.Forms.ExplorerBrowserContentSectionOptions.NoWebView) + | Vanara.Windows.Forms.ExplorerBrowserContentSectionOptions.UseSearchFolder))); + this.explorerBrowser.Dock = System.Windows.Forms.DockStyle.Fill; + this.explorerBrowser.Location = new System.Drawing.Point(3, 32); + this.explorerBrowser.Name = "explorerBrowser"; + this.explorerBrowser.NavigationFlags = Vanara.Windows.Forms.ExplorerBrowserNavigateOptions.ShowFrames; + this.explorerBrowser.PaneVisibility.AdvancedQuery = Vanara.Windows.Forms.PaneVisibilityState.Hide; + this.explorerBrowser.PaneVisibility.Commands = Vanara.Windows.Forms.PaneVisibilityState.Hide; + this.explorerBrowser.PaneVisibility.CommandsOrganize = Vanara.Windows.Forms.PaneVisibilityState.Hide; + this.explorerBrowser.PaneVisibility.CommandsView = Vanara.Windows.Forms.PaneVisibilityState.Hide; + this.explorerBrowser.PaneVisibility.Navigation = Vanara.Windows.Forms.PaneVisibilityState.Hide; + this.explorerBrowser.PaneVisibility.Query = Vanara.Windows.Forms.PaneVisibilityState.Hide; + this.explorerBrowser.PaneVisibility.Ribbon = Vanara.Windows.Forms.PaneVisibilityState.Hide; + this.explorerBrowser.PaneVisibility.StatusBar = Vanara.Windows.Forms.PaneVisibilityState.Hide; + this.explorerBrowser.Size = new System.Drawing.Size(616, 557); + this.explorerBrowser.TabIndex = 0; + this.explorerBrowser.ViewMode = Vanara.Windows.Forms.ExplorerBrowserViewMode.SmallIcon; + // + // titleLabel + // + this.titleLabel.AutoSize = true; + this.titleLabel.Dock = System.Windows.Forms.DockStyle.Left; + this.titleLabel.Font = new System.Drawing.Font("Segoe UI", 14F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.titleLabel.Location = new System.Drawing.Point(3, 0); + this.titleLabel.Name = "titleLabel"; + this.titleLabel.Padding = new System.Windows.Forms.Padding(3, 0, 7, 0); + this.titleLabel.Size = new System.Drawing.Size(10, 29); + this.titleLabel.TabIndex = 1; + // + // runButton + // + this.runButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.runButton.Location = new System.Drawing.Point(518, 3); + this.runButton.Name = "runButton"; + this.runButton.Size = new System.Drawing.Size(101, 23); + this.runButton.TabIndex = 2; + this.runButton.Text = "Run in console"; + this.runButton.UseVisualStyleBackColor = true; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(891, 592); + this.Controls.Add(this.tableLayoutPanel1); + this.Controls.Add(this.splitter1); + this.Controls.Add(this.projectView); + this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Name = "Form1"; + this.Text = "Windows Classic Samples Explorer"; + this.Load += new System.EventHandler(this.Form1_Load); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView projectView; + private System.Windows.Forms.Splitter splitter1; + private System.ComponentModel.BackgroundWorker treeLoader; + private System.Windows.Forms.ImageList treeViewImageList; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private Vanara.Windows.Forms.ExplorerBrowser explorerBrowser; + private System.Windows.Forms.Label titleLabel; + private System.Windows.Forms.Button runButton; + } +} + diff --git a/Sampler/Form1.cs b/Sampler/Form1.cs new file mode 100644 index 00000000..143255cd --- /dev/null +++ b/Sampler/Form1.cs @@ -0,0 +1,150 @@ +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Windows.Forms; +using Vanara.Extensions; +using Vanara.PInvoke; +using Vanara.Windows.Shell; +using static Vanara.PInvoke.ComCtl32; +using static Vanara.PInvoke.Shell32; + +namespace Sampler; + +public partial class Form1 : Form +{ + private const string folderKey = "5EEB255733234c4dBECF9A128E896A1E"; + private const char sep = '\\'; + + private DirectoryInfo[] topDirs = []; + + public Form1() => InitializeComponent(); + + private static DirectoryInfo RootPath => new(Environment.ExpandEnvironmentVariables(Properties.Settings.Default.Root)); + + private static void AddLeaf(TreeNode root, FileInfo leaf, ImageList imageList) + { + var fullLeafPath = leaf.FullName; + var relLeafPath = fullLeafPath.Substring(root.Name.Length).TrimStart(sep); + var leafPathParts = relLeafPath.Split(sep); + + var curParent = root; + for (int i = 0; i < leafPathParts.Length - 1; i++) + { + var childKey = Path.Combine(curParent.Name, leafPathParts[i]); + var childIdx = curParent.Nodes.IndexOfKey(childKey); + curParent = childIdx == -1 ? AddSystemNode(curParent.Nodes, childKey, imageList) : curParent.Nodes[childIdx]; + } + } + + private static TreeNode AddSystemNode(TreeNodeCollection parent, string systemItemPath, ImageList imageList) + { + string ext, ilkey; + if (File.Exists(systemItemPath)) + { + ext = Path.GetExtension(systemItemPath); + if (ext.Equals(".exe", StringComparison.InvariantCultureIgnoreCase) || ext.Equals(".lnk", StringComparison.InvariantCultureIgnoreCase)) + ext = systemItemPath; + ilkey = ext; + } + else + { + ext = ilkey = folderKey; + } + + if (!imageList.Images.ContainsKey(ilkey)) + { + try + { + if (ilkey == folderKey) + imageList.Images.Add(ilkey, GetSystemIcon()!); + else + imageList.Images.Add(ilkey, IconExtension.GetFileIcon(ext, IconSize.Small)!.ToBitmap()); + } + catch (ArgumentException ex) + { + throw new ArgumentException($"File \"{systemItemPath}\" does" + " not exist!", ex); + } + } + return parent.Add(systemItemPath, Path.GetFileName(systemItemPath), ilkey, ilkey); + } + + private static Bitmap? GetSystemIcon() + { + var shfi = new SHFILEINFO(); + HIMAGELIST hSystemImageList = SHGetFileInfo("", 0, ref shfi, SHFILEINFO.Size, SHGFI.SHGFI_SYSICONINDEX | SHGFI.SHGFI_SMALLICON); + return hSystemImageList.IsNull ? null : ImageList_GetIcon(hSystemImageList, shfi.iIcon, IMAGELISTDRAWFLAGS.ILD_TRANSPARENT)?.ToBitmap(); + } + + private void explorerBrowser_SelectionChanged(object sender, EventArgs e) + { + } + + private void Form1_Load(object sender, EventArgs e) + { + //treeLoader.RunWorkerAsync(); + projectView.BeginUpdate(); + projectView.Nodes.Clear(); + LoadTree(); + projectView.EndUpdate(); + } + + private void LoadTree() + { + var root = projectView.Nodes.Add(RootPath.FullName, "Samples"); + root.Expand(); + foreach (var fi in RootPath.EnumerateFiles("*.csproj", SearchOption.AllDirectories)) + { + if (!fi.DirectoryName!.EndsWith("\\Sampler")) + AddLeaf(root, fi, projectView.ImageList); + } + } + + private void projectView_AfterSelect(object sender, TreeViewEventArgs e) + { + var di = new DirectoryInfo(e.Node!.Name); + var prj = di.Exists ? di.EnumerateFiles("*.csproj").FirstOrDefault() : null; + explorerBrowser.Navigate(new ShellFolder(e.Node.Name)); + if (prj != null) + { + titleLabel.Text = Path.GetFileNameWithoutExtension(prj.Name); + } + else + { + titleLabel.Text = "[None]"; + } + } + + private void runButton_Click(object sender, EventArgs e) + { + MessageBox.Show("This is a placeholder for running the selected sample project. Implementing this functionality remains to do."); + //var session = conEmuControl1.Start(new ConEmuStartInfo() + //{ + // AnsiStreamChunkReceivedEventSink = (sender, args) => sbText.Append(args.GetMbcsText()), + // ConsoleProcessCommandLine = "ping 8.8.8.8", + // LogLevel = ConEmuStartInfo.LogLevels.Basic + //}); + //session.ConsoleProcessExited += delegate + //{ + // var match = Regex.Match(sbText.ToString(), @"\(.*\b(?\d+)%.*?\)", RegexOptions.Multiline); + // if (!match.Success) + // { + // labelWaitOrResult.Text = "Ping execution completed, failed to parse the result."; + // labelWaitOrResult.BackColor = Color.PaleVioletRed; + // } + // else + // { + // labelWaitOrResult.Text = $"Ping execution completed, lost {match.Groups["pc"].Value} per cent of packets."; + // labelWaitOrResult.BackColor = Color.Lime; + // } + //}; + //session.ConsoleEmulatorClosed += delegate { form.Close(); }; + } + + private void treeLoader_DoWork(object sender, DoWorkEventArgs e) + { + } + + private void treeLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + } +} \ No newline at end of file diff --git a/Sampler/Form1.resx b/Sampler/Form1.resx new file mode 100644 index 00000000..c22f54a7 --- /dev/null +++ b/Sampler/Form1.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 127, 17 + + + 17, 17 + + \ No newline at end of file diff --git a/Sampler/NuGetPackages.Designer.cs b/Sampler/NuGetPackages.Designer.cs new file mode 100644 index 00000000..a9ff66ad --- /dev/null +++ b/Sampler/NuGetPackages.Designer.cs @@ -0,0 +1,140 @@ +namespace Sampler; + +partial class NuGetPackages +{ + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + listBox1 = new System.Windows.Forms.ListBox(); + listBox2 = new System.Windows.Forms.ListBox(); + splitContainer1 = new System.Windows.Forms.SplitContainer(); + splitContainer2 = new System.Windows.Forms.SplitContainer(); + listBox3 = new System.Windows.Forms.ListBox(); + ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit(); + splitContainer1.Panel1.SuspendLayout(); + splitContainer1.Panel2.SuspendLayout(); + splitContainer1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)splitContainer2).BeginInit(); + splitContainer2.Panel1.SuspendLayout(); + splitContainer2.Panel2.SuspendLayout(); + splitContainer2.SuspendLayout(); + SuspendLayout(); + // + // listBox1 + // + listBox1.Dock = System.Windows.Forms.DockStyle.Fill; + listBox1.FormattingEnabled = true; + listBox1.ItemHeight = 25; + listBox1.Items.AddRange(new object[] { "Loading..." }); + listBox1.Location = new System.Drawing.Point(0, 0); + listBox1.Name = "listBox1"; + listBox1.Size = new System.Drawing.Size(282, 654); + listBox1.TabIndex = 0; + listBox1.SelectedIndexChanged += listBox1_SelectedIndexChanged; + // + // listBox2 + // + listBox2.Dock = System.Windows.Forms.DockStyle.Fill; + listBox2.FormattingEnabled = true; + listBox2.ItemHeight = 25; + listBox2.Location = new System.Drawing.Point(0, 0); + listBox2.Name = "listBox2"; + listBox2.Size = new System.Drawing.Size(187, 654); + listBox2.TabIndex = 1; + listBox2.SelectedIndexChanged += listBox2_SelectedIndexChanged; + // + // splitContainer1 + // + splitContainer1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + splitContainer1.Location = new System.Drawing.Point(12, 12); + splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + splitContainer1.Panel1.Controls.Add(listBox1); + // + // splitContainer1.Panel2 + // + splitContainer1.Panel2.Controls.Add(splitContainer2); + splitContainer1.Size = new System.Drawing.Size(848, 654); + splitContainer1.SplitterDistance = 282; + splitContainer1.TabIndex = 2; + // + // splitContainer2 + // + splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; + splitContainer2.Location = new System.Drawing.Point(0, 0); + splitContainer2.Name = "splitContainer2"; + // + // splitContainer2.Panel1 + // + splitContainer2.Panel1.Controls.Add(listBox2); + // + // splitContainer2.Panel2 + // + splitContainer2.Panel2.Controls.Add(listBox3); + splitContainer2.Size = new System.Drawing.Size(562, 654); + splitContainer2.SplitterDistance = 187; + splitContainer2.TabIndex = 0; + // + // listBox3 + // + listBox3.Dock = System.Windows.Forms.DockStyle.Fill; + listBox3.FormattingEnabled = true; + listBox3.ItemHeight = 25; + listBox3.Location = new System.Drawing.Point(0, 0); + listBox3.Name = "listBox3"; + listBox3.Size = new System.Drawing.Size(371, 654); + listBox3.TabIndex = 2; + // + // NuGetPackages + // + AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(872, 678); + Controls.Add(splitContainer1); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + Name = "NuGetPackages"; + Text = "NuGetPackages"; + splitContainer1.Panel1.ResumeLayout(false); + splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit(); + splitContainer1.ResumeLayout(false); + splitContainer2.Panel1.ResumeLayout(false); + splitContainer2.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)splitContainer2).EndInit(); + splitContainer2.ResumeLayout(false); + ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.ListBox listBox2; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.SplitContainer splitContainer2; + private System.Windows.Forms.ListBox listBox3; +} \ No newline at end of file diff --git a/Sampler/NuGetPackages.cs b/Sampler/NuGetPackages.cs new file mode 100644 index 00000000..db2f7590 --- /dev/null +++ b/Sampler/NuGetPackages.cs @@ -0,0 +1,74 @@ +using NuGet.Common; +using NuGet.Frameworks; +using NuGet.Packaging.Core; +using NuGet.Protocol.Core.Types; +using System.Data; +using System.IO; +using System.Runtime.Versioning; +using System.Threading.Tasks; +using System.Windows.Forms; +[assembly: SupportedOSPlatform("windows")] + +namespace Sampler; + +public partial class NuGetPackages : Form +{ + const string framework = "net8.0"; + private const string Prefix = "Vanara"; + readonly List packages = []; + static readonly ILogger logger = NullLogger.Instance; // TODO: Replace with actual logger if needed + static readonly CancellationToken cancellationToken = CancellationToken.None; // TODO: Replace with actual cancellation token if needed + + public NuGetPackages() => InitializeComponent(); + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + listBox1.Format += (s, args) => args.Value = args.ListItem is IPackageSearchMetadata r ? r.Title : args.ListItem?.ToString() ?? string.Empty; + Task.Factory.StartNew(async () => + { + await foreach (var package in NuGetUtils.LoadNuGetPackageListAsync(Prefix, logger, cancellationToken)) + if (package.Identity.Id.StartsWith(Prefix + '.', StringComparison.OrdinalIgnoreCase)) + packages.Add(package); + listBox1.Invoke(() => { listBox1.Items.Clear(); listBox1.DataSource = packages; }); + }, cancellationToken); + } + + protected override void OnFormClosing(FormClosingEventArgs e) + { + try { Directory.Delete(Path.Combine(Path.GetTempPath(), "NuGetDownloads"), true); } catch { } + base.OnFormClosing(e); + } + + private void listBox1_SelectedIndexChanged(object sender, EventArgs e) + { + listBox2.Items.Clear(); + if (listBox1.SelectedItem is IPackageSearchMetadata metadata) + Task.Factory.StartNew(() => + { + string[] items = NuGetUtils.LoadPackageVersionsAsync(metadata, logger, cancellationToken).Result; + listBox2.Invoke(() => listBox2.Items.AddRange(items)); + }, cancellationToken); + } + + private void listBox2_SelectedIndexChanged(object sender, EventArgs e) + { + listBox3.Items.Clear(); + if (listBox1.SelectedItem is IPackageSearchMetadata metadata && listBox2.SelectedItem is string ver) + { + listBox3.Items.Add("Getting dependencies..."); + Task.Factory.StartNew(async () => + { + HashSet dependencies = []; + await NuGetUtils.ResolveDependenciesAsync(metadata.Identity, NuGetFramework.Parse(framework), dependencies, null, logger, cancellationToken); + listBox3.Invoke(() => listBox3.Items[0] = "Downloading packages..."); + string downloadDir = Path.Combine(Path.GetTempPath(), "NuGetDownloads"); + await NuGetUtils.DownloadPackagesAsync(dependencies.Select(dep => new PackageIdentity(dep.Id, dep.Version)).Where(id => id.Id.StartsWith(Prefix + '.', StringComparison.OrdinalIgnoreCase)), downloadDir, logger, cancellationToken); + listBox3.Invoke(() => listBox3.Items[0] = "Extracting files..."); + string extractDir = Path.Combine(downloadDir, "extracted"); + await NuGetUtils.ExtractAssembliesFromPacakgesAsync(downloadDir, framework, extractDir, logger, cancellationToken); + listBox3.Invoke(() => { listBox3.Items.Clear(); listBox3.Items.AddRange(Array.ConvertAll(Directory.GetFiles(extractDir), Path.GetFileName)!); }); + }, cancellationToken); + } + } +} \ No newline at end of file diff --git a/Sampler/NuGetPackages.resx b/Sampler/NuGetPackages.resx new file mode 100644 index 00000000..8b2ff64a --- /dev/null +++ b/Sampler/NuGetPackages.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Sampler/NuGetUtils.cs b/Sampler/NuGetUtils.cs new file mode 100644 index 00000000..75909774 --- /dev/null +++ b/Sampler/NuGetUtils.cs @@ -0,0 +1,106 @@ +using NuGet.Common; +using NuGet.Frameworks; +using NuGet.Packaging; +using NuGet.Packaging.Core; +using NuGet.Protocol; +using NuGet.Protocol.Core.Types; +using System.Data; +using System.IO; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace Sampler; + +internal static class NuGetUtils +{ + private static readonly SourceCacheContext cacheContext = new(); + private static readonly SourceRepository repository = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json"); + + public static async Task DownloadPackagesAsync(IEnumerable packageIds, string downloadDirectory, ILogger? logger, CancellationToken cancellationToken) + { + foreach (PackageIdentity packageIdentity in packageIds) + { + logger?.LogInformation($"Downloading package: {packageIdentity}"); + DownloadResource downloadResource = await repository.GetResourceAsync(cancellationToken); + DownloadResourceResult result = await downloadResource.GetDownloadResourceResultAsync(packageIdentity, new PackageDownloadContext(new SourceCacheContext()), downloadDirectory, logger, cancellationToken); + if (result.Status == DownloadResourceResultStatus.Available) + { + // Save the .nupkg file to the download directory + string destinationPath = Path.Combine(downloadDirectory, $"{packageIdentity.Id}.{packageIdentity.Version}.nupkg"); + using FileStream fileStream = File.Create(destinationPath); + await result.PackageStream.CopyToAsync(fileStream, cancellationToken); + fileStream.Close(); + } + } + } + + public static async Task ExtractAssembliesFromPacakgesAsync(string packagesDirectory, string dotnetVersion, string extractionDirectory, ILogger? logger, CancellationToken cancellationToken) + { + var targetFramework = NuGetFramework.Parse(dotnetVersion); + IFrameworkNameProvider frameworkNameProvider = DefaultFrameworkNameProvider.Instance; + var reducer = new FrameworkReducer(frameworkNameProvider, DefaultCompatibilityProvider.Instance); + Directory.CreateDirectory(extractionDirectory); + foreach (var packageFile in Directory.EnumerateFiles(packagesDirectory, "*.nupkg")) + { + logger?.LogInformation($"Processing package: {packageFile}"); + using var packageReader = new PackageArchiveReader(packageFile); + IEnumerable libItems = await packageReader.GetLibItemsAsync(cancellationToken); + NuGetFramework? bestMatch = reducer.GetNearest(targetFramework, libItems.Select(x => x.TargetFramework)); + foreach (var assemblyPath in libItems.FirstOrDefault(i => i.TargetFramework.Equals(bestMatch))?.Items.Where(i => i.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || i.EndsWith(".nuspec", StringComparison.OrdinalIgnoreCase)) ?? []) + { + logger?.LogInformation($"Extracting assembly: {assemblyPath} from package: {packageFile}"); + using Stream assemblyStream = packageReader.GetStream(assemblyPath); + using FileStream fileStream = File.Create(Path.Combine(extractionDirectory, Path.GetFileName(assemblyPath))); + await assemblyStream.CopyToAsync(fileStream, cancellationToken); + } + } + } + + public static async IAsyncEnumerable LoadNuGetPackageListAsync(string prefix, ILogger? logger, [EnumeratorCancellation] CancellationToken cancellationToken) + { + // Get the search resource from the repository + PackageSearchResource searchResource = await repository.GetResourceAsync(cancellationToken); + + // Set search filters (e.g., include pre-release versions) + SearchFilter searchFilter = new(false, SearchFilterType.IsLatestVersion); + + // Execute the search (take the top 10 results) + int skip = 0; + const int maxTake = 150, chunkSize = 30; + while (skip < maxTake) + { + bool found = false; + foreach (IPackageSearchMetadata? m in await searchResource.SearchAsync(prefix, searchFilter, skip: skip, take: chunkSize, logger, cancellationToken)) + { + found = true; + yield return m; + } + if (!found) + break; + skip += chunkSize; + } + } + + public static async Task LoadPackageVersionsAsync(IPackageSearchMetadata metadata, ILogger? logger, CancellationToken cancellationToken) => + [.. metadata.GetVersionsAsync().Result.OrderByDescending(v => v.Version).Select(v => v.Version.ToString()!)]; + + public static async Task ResolveDependenciesAsync(PackageIdentity package, NuGetFramework framework, HashSet allPackages, DependencyInfoResource? depResource, ILogger? logger, CancellationToken cancellationToken) + { + if (allPackages.Contains(package)) return; + + depResource ??= await repository.GetResourceAsync(cancellationToken); + SourcePackageDependencyInfo dependencyInfo = await depResource.ResolvePackage(package, framework, cacheContext, logger, cancellationToken); + if (cancellationToken.IsCancellationRequested) return; + if (dependencyInfo != null) + { + allPackages.Add(dependencyInfo); + foreach (PackageDependency dependency in dependencyInfo.Dependencies) + { + if (cancellationToken.IsCancellationRequested) return; + logger?.LogInformation($"Resolving dependency: {dependency.Id} {dependency.VersionRange}"); + var depIdentity = new PackageIdentity(dependency.Id, dependency.VersionRange.MinVersion); + await ResolveDependenciesAsync(depIdentity, framework, allPackages, depResource, logger, cancellationToken); + } + } + } +} \ No newline at end of file diff --git a/Sampler/Program.cs b/Sampler/Program.cs new file mode 100644 index 00000000..ab546a09 --- /dev/null +++ b/Sampler/Program.cs @@ -0,0 +1,15 @@ +using System.Windows.Forms; + +namespace Sampler; + + +static class Program +{ + /// The main entry point for the application. + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new NuGetPackages()); + } +} \ No newline at end of file diff --git a/Sampler/Properties/AssemblyInfo.cs b/Sampler/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..84fee451 --- /dev/null +++ b/Sampler/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Sampler")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Sampler")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("42d061df-6c64-4907-b23b-38eaae1ec701")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Sampler/Properties/Resources.Designer.cs b/Sampler/Properties/Resources.Designer.cs new file mode 100644 index 00000000..40431901 --- /dev/null +++ b/Sampler/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Sampler.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Sampler.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Sampler/Properties/Resources.resx b/Sampler/Properties/Resources.resx new file mode 100644 index 00000000..af7dbebb --- /dev/null +++ b/Sampler/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Sampler/Properties/Settings.Designer.cs b/Sampler/Properties/Settings.Designer.cs new file mode 100644 index 00000000..1f9a7960 --- /dev/null +++ b/Sampler/Properties/Settings.Designer.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Sampler.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "18.4.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("%USERPROFILE%\\Documents\\GitHubRepos\\WinClassicSamplesCS")] + public string Root { + get { + return ((string)(this["Root"])); + } + set { + this["Root"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Sampler")] + public string IgnoreFolders { + get { + return ((string)(this["IgnoreFolders"])); + } + set { + this["IgnoreFolders"] = value; + } + } + } +} diff --git a/Sampler/Properties/Settings.settings b/Sampler/Properties/Settings.settings new file mode 100644 index 00000000..096cb673 --- /dev/null +++ b/Sampler/Properties/Settings.settings @@ -0,0 +1,12 @@ + + + + + + %USERPROFILE%\Documents\GitHubRepos\WinClassicSamplesCS + + + Sampler + + + \ No newline at end of file diff --git a/Sampler/Sampler.csproj b/Sampler/Sampler.csproj new file mode 100644 index 00000000..7c8fae97 --- /dev/null +++ b/Sampler/Sampler.csproj @@ -0,0 +1,39 @@ + + + WinExe + windows + false + true + latest + + + + + + + + + + + + + + + + + + + + True + True + Settings.settings + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + Sampler.Properties + + + \ No newline at end of file diff --git a/Security/CodeSigning/Program.cs b/Security/CodeSigning/Program.cs index 8bb3957b..72ed6d40 100644 --- a/Security/CodeSigning/Program.cs +++ b/Security/CodeSigning/Program.cs @@ -105,7 +105,7 @@ private static Win32Error VerifyCatalogSignature(HFILE FileHandle, bool UseStron { CERT_STRONG_SIGN_PARA SigningPolicy = new() { - cbSize = (uint)Marshal.SizeOf(typeof(CERT_STRONG_SIGN_PARA)), + cbSize = (uint)Marshal.SizeOf(), dwInfoChoice = CERT_INFO_CHOICE.CERT_STRONG_SIGN_OID_INFO_CHOICE, pszOID = mem.Add(SignOID.szOID_CERT_STRONG_SIGN_OS_CURRENT, CharSet.Ansi) }; @@ -145,7 +145,7 @@ private static Win32Error VerifyCatalogSignature(HFILE FileHandle, bool UseStron while (!CatInfoHandle.IsNull) { - CATALOG_INFO catalogInfo = new() { cbStruct = (uint)Marshal.SizeOf(typeof(CATALOG_INFO)) }; + CATALOG_INFO catalogInfo = new() { cbStruct = (uint)Marshal.SizeOf() }; Found = true; if (!CryptCATCatalogInfoFromContext(CatInfoHandle, ref catalogInfo)) @@ -185,7 +185,7 @@ private static HRESULT VerifyEmbeddedSignatures(string FileName, HFILE FileHandl // Setup data structures for calling WinVerifyTrustEx WINTRUST_FILE_INFO FileInfo = new() { - cbStruct = (uint)Marshal.SizeOf(typeof(WINTRUST_FILE_INFO)), + cbStruct = (uint)Marshal.SizeOf(), hFile = FileHandle, pcwszFilePath = mem.Add(FileName, CharSet.Unicode) }; @@ -194,7 +194,7 @@ private static HRESULT VerifyEmbeddedSignatures(string FileName, HFILE FileHandl // and dwIndex to do this, also setting WSS_GET_SECONDARY_SIG_COUNT to have the number of secondary signatures returned. WINTRUST_SIGNATURE_SETTINGS SignatureSettings = new() { - cbStruct = (uint)Marshal.SizeOf(typeof(WINTRUST_SIGNATURE_SETTINGS)), + cbStruct = (uint)Marshal.SizeOf(), dwFlags = WSS.WSS_GET_SECONDARY_SIG_COUNT | WSS.WSS_VERIFY_SPECIFIC, dwIndex = 0 }; @@ -203,7 +203,7 @@ private static HRESULT VerifyEmbeddedSignatures(string FileName, HFILE FileHandl { CERT_STRONG_SIGN_PARA StrongSigPolicy = new() { - cbSize = (uint)Marshal.SizeOf(typeof(CERT_STRONG_SIGN_PARA)), + cbSize = (uint)Marshal.SizeOf(), dwInfoChoice = CERT_INFO_CHOICE.CERT_STRONG_SIGN_OID_INFO_CHOICE, pszOID = mem.Add(SignOID.szOID_CERT_STRONG_SIGN_OS_CURRENT, CharSet.Ansi) }; diff --git a/Security/ResourceAttributes/ResourceAttributesSample.cs b/Security/ResourceAttributes/ResourceAttributesSample.cs index e8cd59a6..2dc42c86 100644 --- a/Security/ResourceAttributes/ResourceAttributesSample.cs +++ b/Security/ResourceAttributes/ResourceAttributesSample.cs @@ -382,7 +382,7 @@ ACE to a security descriptor. // Get the entire size required for the resource attribute structure, so we // can allocate a single block of contiguous memory. SizeT NameBytes = AttributeTokens.Name.GetByteCount(true, CharSet.Unicode); - SizeT ByteCount = ALIGN(Marshal.SizeOf(typeof(CLAIM_SECURITY_ATTRIBUTE_V1))); + SizeT ByteCount = ALIGN(Marshal.SizeOf()); SizeT offset = ByteCount; ByteCount += ALIGN(NameBytes); ByteCount += ALIGN(Values.Length * GetValueSize(ValueType)); @@ -661,8 +661,8 @@ uint GetValueSize(CLAIM_SECURITY_ATTRIBUTE_TYPE ClaimType) { var Size = ClaimType switch { - CLAIM_SECURITY_ATTRIBUTE_TYPE.CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64 => Marshal.SizeOf(typeof(long)), - CLAIM_SECURITY_ATTRIBUTE_TYPE.CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64 or CLAIM_SECURITY_ATTRIBUTE_TYPE.CLAIM_SECURITY_ATTRIBUTE_TYPE_BOOLEAN => Marshal.SizeOf(typeof(ulong)), + CLAIM_SECURITY_ATTRIBUTE_TYPE.CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64 => Marshal.SizeOf(), + CLAIM_SECURITY_ATTRIBUTE_TYPE.CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64 or CLAIM_SECURITY_ATTRIBUTE_TYPE.CLAIM_SECURITY_ATTRIBUTE_TYPE_BOOLEAN => Marshal.SizeOf(), CLAIM_SECURITY_ATTRIBUTE_TYPE.CLAIM_SECURITY_ATTRIBUTE_TYPE_STRING => IntPtr.Size, _ => 0, }; diff --git a/WASAPIRendering/Program.cs b/WASAPIRendering/Program.cs index 45f44680..dfa0776a 100644 --- a/WASAPIRendering/Program.cs +++ b/WASAPIRendering/Program.cs @@ -234,7 +234,7 @@ void GenerateSineSamples(byte[] Buffer, uint Frequency, ushort ChannelCount, T* dataBuffer = (T*)pBuffer; double theta = InitialTheta; - for (int i = 0; i < Buffer.Length / Marshal.SizeOf(typeof(T)); i += ChannelCount) + for (int i = 0; i < Buffer.Length / Marshal.SizeOf(); i += ChannelCount) { double sinValue = Math.Sin(theta); for (ushort j = 0; j < ChannelCount; j++) diff --git a/Win7Samples/dataaccess/oledb/prsample/rowset.cs b/Win7Samples/dataaccess/oledb/prsample/rowset.cs index c5ddcb5c..63b3ef19 100644 --- a/Win7Samples/dataaccess/oledb/prsample/rowset.cs +++ b/Win7Samples/dataaccess/oledb/prsample/rowset.cs @@ -653,7 +653,7 @@ private static void mySetupBindings(IRowset pUnkRowset, out DBBINDING[] prgBindi // include space // for the include // space for the - // NULL-terminator Marshal.SizeOf(typeof(ushort)); + // NULL-terminator Marshal.SizeOf(); _ => MAX_COL_SIZE,// For any other type, we will simply use our maximum // column buffer size, since the display size of these columns may be variable (e.g. DBTYPE_VARIANT) or // unknown (e.g. provider-specific types) diff --git a/Win7Samples/netds/Qos/Qos2/qossample.cs b/Win7Samples/netds/Qos/Qos2/qossample.cs index e740f65f..136372e9 100644 --- a/Win7Samples/netds/Qos/Qos2/qossample.cs +++ b/Win7Samples/netds/Qos/Qos2/qossample.cs @@ -625,7 +625,7 @@ void client([In] string[] args) // congested and bandwidth is available. targetBandwidthWithOverhead = QOS_ADD_OVERHEAD(addressFamily, IPPROTO.IPPROTO_UDP, dataBuffer.Size, targetBitRate); - bufferSize = (uint)Marshal.SizeOf(typeof(ulong)); + bufferSize = (uint)Marshal.SizeOf(); result = QOSNotifyFlow(qosHandle, flowID, QOS_NOTIFY_FLOW.QOSNotifyAvailable, targetBandwidthWithOverhead, ref availableOverlapped); if (result == false) diff --git a/Win7Samples/netds/Qos/TCSample/TCSample.cs b/Win7Samples/netds/Qos/TCSample/TCSample.cs index 93989928..d88dbb04 100644 --- a/Win7Samples/netds/Qos/TCSample/TCSample.cs +++ b/Win7Samples/netds/Qos/TCSample/TCSample.cs @@ -317,7 +317,7 @@ bool CreateFlow(out TC_GEN_FLOW pTcFlowObj, ushort DSCPValue, ushort OnePValue, { QOS_TRAFFIC_CLASS pTClassObject = new(); pTClassObject.ObjectHdr.ObjectType = QOS_OBJ_TYPE.QOS_OBJECT_TRAFFIC_CLASS; - pTClassObject.ObjectHdr.ObjectLength = (uint)Marshal.SizeOf(typeof(QOS_TRAFFIC_CLASS)); + pTClassObject.ObjectHdr.ObjectLength = (uint)Marshal.SizeOf(); pTClassObject.TrafficClass = OnePValue; //802.1p tag to be used pTcFlowObj.TcObjects[0] = pTClassObject; } @@ -326,7 +326,7 @@ bool CreateFlow(out TC_GEN_FLOW pTcFlowObj, ushort DSCPValue, ushort OnePValue, { QOS_DS_CLASS pDSClassObject = new(); pDSClassObject.ObjectHdr.ObjectType = QOS_OBJ_TYPE.QOS_OBJECT_DS_CLASS; - pDSClassObject.ObjectHdr.ObjectLength = (uint)Marshal.SizeOf(typeof(QOS_DS_CLASS)); + pDSClassObject.ObjectHdr.ObjectLength = (uint)Marshal.SizeOf(); pDSClassObject.DSField = DSCPValue; //Services Type pTcFlowObj.TcObjects[OnePValue != NOT_SPECIFIED ? 0 : 1] = pDSClassObject; } @@ -460,7 +460,7 @@ bool CreateFilter(out TC_GEN_FILTER pFilter, SOCKADDR_STORAGE Address, ushort Po } pFilter.AddressType = NDIS_PROTOCOL_ID.NDIS_PROTOCOL_ID_TCP_IP; - pFilter.PatternSize = (uint)Marshal.SizeOf(typeof(IP_PATTERN)); + pFilter.PatternSize = (uint)Marshal.SizeOf(); pFilter.Pattern = pPattern.MarshalToPtr(Marshal.AllocHGlobal, out _); pFilter.Mask = pMask.MarshalToPtr(Marshal.AllocHGlobal, out _); diff --git a/Win7Samples/netds/dns/ModifyRecords/ModifyRecords.cs b/Win7Samples/netds/dns/ModifyRecords/ModifyRecords.cs index d1aa8fce..158a70f1 100644 --- a/Win7Samples/netds/dns/ModifyRecords/ModifyRecords.cs +++ b/Win7Samples/netds/dns/ModifyRecords/ModifyRecords.cs @@ -37,7 +37,7 @@ case 'd': if (myDnsRecord.wType == DNS_TYPE.DNS_TYPE_A) { - myDnsRecord.wDataLength = (ushort)Marshal.SizeOf(typeof(DNS_A_DATA)); //data structure for A records + myDnsRecord.wDataLength = (ushort)Marshal.SizeOf(); //data structure for A records var HostipAddress = inet_addr(args[++i]); myDnsRecord.Data = new DNS_A_DATA() { IpAddress = HostipAddress }; //convert string to proper address if (HostipAddress == IN_ADDR.INADDR_NONE) @@ -49,7 +49,7 @@ } else { - myDnsRecord.wDataLength = (ushort)Marshal.SizeOf(typeof(DNS_PTR_DATA)); //data structure for CNAME records + myDnsRecord.wDataLength = (ushort)Marshal.SizeOf(); //data structure for CNAME records myDnsRecord.Data = new DNS_PTR_DATA { pNameHost = args[++i] }; break; } diff --git a/Win7Samples/netds/http/HttpV2Server/main.cs b/Win7Samples/netds/http/HttpV2Server/main.cs index 729dfd38..78a48930 100644 --- a/Win7Samples/netds/http/HttpV2Server/main.cs +++ b/Win7Samples/netds/http/HttpV2Server/main.cs @@ -164,7 +164,7 @@ private static Win32Error DoReceiveRequests([In] HREQQUEUE hReqQueue) Win32Error result = 0; // Allocate a 2K buffer. Should be good for most requests, we'll grow this if required. We also need space for a HTTP_REQUEST structure. - using var pRequestBuffer = new SafeCoTaskMemHandle(Marshal.SizeOf(typeof(HTTP_REQUEST_V1)) + 2048); + using var pRequestBuffer = new SafeCoTaskMemHandle(Marshal.SizeOf() + 2048); // Wait for a new request -- This is indicated by a default request ID. while (HttpReceiveHttpRequest(hReqQueue, HTTP_NULL_ID, 0, out HTTP_REQUEST? pRequest).Succeeded) diff --git a/Win7Samples/netds/http/ServiceConfig4/ssl.cs b/Win7Samples/netds/http/ServiceConfig4/ssl.cs index 9ecf9b31..3dafa9d1 100644 --- a/Win7Samples/netds/http/ServiceConfig4/ssl.cs +++ b/Win7Samples/netds/http/ServiceConfig4/ssl.cs @@ -328,11 +328,11 @@ private static void PrintSslRecord(in HTTP_SERVICE_CONFIG_SSL_SET pSsl) uint dwSockAddrLength; if (pSockAddrIn.sin_family == ADDRESS_FAMILY.AF_INET) { - dwSockAddrLength = (uint)Marshal.SizeOf(typeof(SOCKADDR_IN)); + dwSockAddrLength = (uint)Marshal.SizeOf(); } else if (pSockAddrIn.sin_family == ADDRESS_FAMILY.AF_INET6) { - dwSockAddrLength = (uint)Marshal.SizeOf(typeof(SOCKADDR_IN6)); + dwSockAddrLength = (uint)Marshal.SizeOf(); } else { diff --git a/Win7Samples/netds/http/server/main.cs b/Win7Samples/netds/http/server/main.cs index 4b19fac2..8265b358 100644 --- a/Win7Samples/netds/http/server/main.cs +++ b/Win7Samples/netds/http/server/main.cs @@ -101,7 +101,7 @@ private static Win32Error DoReceiveRequests([In] HREQQUEUEv1 hReqQueue) Win32Error result = 0; // Allocate a 2K buffer. Should be good for most requests, we'll grow this if required. We also need space for a HTTP_REQUEST structure. - using var pRequestBuffer = new SafeCoTaskMemHandle(Marshal.SizeOf(typeof(HTTP_REQUEST_V1)) + 2048); + using var pRequestBuffer = new SafeCoTaskMemHandle(Marshal.SizeOf() + 2048); // Wait for a new request -- This is indicated by a default request ID. while (HttpReceiveHttpRequest(hReqQueue, HTTP_NULL_ID, 0, out HTTP_REQUEST? pRequest).Succeeded) diff --git a/Win7Samples/netds/iphelp/enablerouter/enablerouter.cs b/Win7Samples/netds/iphelp/enablerouter/enablerouter.cs index 6ad4eaf2..13671fbc 100644 --- a/Win7Samples/netds/iphelp/enablerouter/enablerouter.cs +++ b/Win7Samples/netds/iphelp/enablerouter/enablerouter.cs @@ -99,7 +99,7 @@ Console.Write("\nRegression Test 1: Do not zero memory for the Overlapped structure\n"); - Console.Write("\nRegression Test 1: ZeroMemory(&Overlapped, Marshal.SizeOf(typeof(Overlapped))) NOT called\n"); + Console.Write("\nRegression Test 1: ZeroMemory(&Overlapped, Marshal.SizeOf()) NOT called\n"); using (var hEvent = CreateEvent()) if (hEvent.IsInvalid) diff --git a/Win7Samples/netds/peertopeer/GroupChat/GroupChat.cs b/Win7Samples/netds/peertopeer/GroupChat/GroupChat.cs index b57746ca..0a50ee86 100644 --- a/Win7Samples/netds/peertopeer/GroupChat/GroupChat.cs +++ b/Win7Samples/netds/peertopeer/GroupChat/GroupChat.cs @@ -270,7 +270,7 @@ internal static void RefreshIdentityCombo(ComboBox hwndCtrl, bool bAddNullIdenti } if (bAddNullIdentity) { - var ni = new PEER_NAME_PAIR { dwSize = (uint)Marshal.SizeOf(typeof(PEER_NAME_PAIR)), pwzFriendlyName = "NULL Identity" }; + var ni = new PEER_NAME_PAIR { dwSize = (uint)Marshal.SizeOf(), pwzFriendlyName = "NULL Identity" }; hwndCtrl.Items.Add(ni); } if (hwndCtrl.Items.Count > 0) diff --git a/Win7Samples/netds/rpc/hello/helloc/hello_c.cs b/Win7Samples/netds/rpc/hello/helloc/hello_c.cs index ba19295d..8c587ea0 100644 --- a/Win7Samples/netds/rpc/hello/helloc/hello_c.cs +++ b/Win7Samples/netds/rpc/hello/helloc/hello_c.cs @@ -49,7 +49,7 @@ public struct hello_MIDL_EXPR_FORMAT_STRING public static readonly RPC_CLIENT_INTERFACE hello___RpcClientInterface = new() { - Length = (uint)Marshal.SizeOf(typeof(RPC_CLIENT_INTERFACE)), + Length = (uint)Marshal.SizeOf(), InterfaceId = new RPC_SYNTAX_IDENTIFIER(new Guid(0x906B0CE0, 0xC70B, 0x1067, 0xB3, 0x17, 0x00, 0xDD, 0x01, 0x06, 0x62, 0xDA), 1, 0), TransferSyntax = new RPC_SYNTAX_IDENTIFIER(new Guid(0x8A885D04, 0x1CEB, 0x11C9, 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60), 2, 0) }; diff --git a/Win7Samples/netds/winsock/recvmsg/Program.cs b/Win7Samples/netds/winsock/recvmsg/Program.cs index 51183af9..73e7d365 100644 --- a/Win7Samples/netds/winsock/recvmsg/Program.cs +++ b/Win7Samples/netds/winsock/recvmsg/Program.cs @@ -219,7 +219,7 @@ static bool SetIpv6PktInfoOption(SafeSOCKET sock) static bool AllocAndInitIpv6PktInfo(ref WSAMSG pWSAMsg) { - pWSAMsg.Control.len = WSA_CMSG_SPACE(Marshal.SizeOf(typeof(IN6_PKTINFO))); + pWSAMsg.Control.len = WSA_CMSG_SPACE(Marshal.SizeOf()); pWSAMsg.Control.buf = Marshal.AllocCoTaskMem((int)pWSAMsg.Control.len); //caller frees heap allocated CtrlBuf return true; } diff --git a/Win7Samples/netds/winsock/wsapoll/Program.cs b/Win7Samples/netds/winsock/wsapoll/Program.cs index 3fcd24d4..f7eba520 100644 --- a/Win7Samples/netds/winsock/wsapoll/Program.cs +++ b/Win7Samples/netds/winsock/wsapoll/Program.cs @@ -34,7 +34,7 @@ public static int Main() using PinnedObject puNonBlockingMode = new(uNonBlockingMode); ioctlsocket(lsock, WinSockIOControlCode.FIONBIO, puNonBlockingMode).ThrowIfFailed(); - bind(lsock, addr, Marshal.SizeOf(typeof(SOCKADDR_IN6))).ThrowIfFailed(); + bind(lsock, addr, Marshal.SizeOf()).ThrowIfFailed(); listen(lsock, 1).ThrowIfFailed(); @@ -93,7 +93,7 @@ private static uint ConnectThread(IntPtr lpParam) SOCKADDR_IN6 addrLoopback = (SOCKADDR_IN6)IN6_ADDR.Loopback; addrLoopback.sin6_port = htons(DEFAULT_PORT); - connect(csock, (SOCKADDR)addrLoopback, Marshal.SizeOf(typeof(SOCKADDR_IN6))).ThrowIfFailed(); + connect(csock, (SOCKADDR)addrLoopback, Marshal.SizeOf()).ThrowIfFailed(); // Call WSAPoll for writeability on connecting socket WSAPOLLFD[] fdarray = [new() { fd = csock, events = PollFlags.POLLWRNORM }]; diff --git a/Win7Samples/security/authorization/aclapi/aclapi.cs b/Win7Samples/security/authorization/aclapi/aclapi.cs index 0ed7a15e..bfea6268 100644 --- a/Win7Samples/security/authorization/aclapi/aclapi.cs +++ b/Win7Samples/security/authorization/aclapi/aclapi.cs @@ -49,10 +49,10 @@ private static int Main(string[] args) BuildExplicitAccessWithName(out var explicitaccess, TrusteeName, AccessMask, option, InheritFlag); // add specified access to the object - SetEntriesInAcl(1, [explicitaccess], ExistingDacl, out var NewAcl).ThrowIfFailed(); + SetEntriesInAcl([explicitaccess], ExistingDacl, out var NewAcl).ThrowIfFailed(); // apply new security to file - SetNamedSecurityInfo(FileName, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, default, default, NewAcl, default).ThrowIfFailed(); + SetNamedSecurityInfo(FileName, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, ppDacl: NewAcl).ThrowIfFailed(); return 0; } diff --git a/Win7Samples/security/authorization/authz/authz.cs b/Win7Samples/security/authorization/authz/authz.cs deleted file mode 100644 index e416121f..00000000 --- a/Win7Samples/security/authorization/authz/authz.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AuthZ; - -internal static class AuthZ -{ - public static int Main(string[] args) - { - return 0; - } -} \ No newline at end of file diff --git a/Win7Samples/security/authorization/authz/authzcli.cs b/Win7Samples/security/authorization/authz/authzcli.cs new file mode 100644 index 00000000..417c1778 --- /dev/null +++ b/Win7Samples/security/authorization/authz/authzcli.cs @@ -0,0 +1,123 @@ +using Vanara.InteropServices; +using Vanara.PInvoke; +using static Common; +using static Vanara.PInvoke.Kernel32; + +internal partial class Program +{ + const string pwd = "Pa$$w0rd"; + static readonly ManualResetEventSlim svrExit = new(false); + static readonly Dictionary ExTypes = new(StringComparer.InvariantCultureIgnoreCase) + { + ["Personal"] = ACCESS_FUND.ACCESS_FUND_PERSONAL, + ["Corporate"] = ACCESS_FUND.ACCESS_FUND_CORPORATE, + ["Transfer"] = ACCESS_FUND.ACCESS_FUND_TRANSFER, + }; + + private static void Main() + { + string szServerName = "\\\\."; + EX_BUF exBuf = default; + + Console.Write("\nRun client as 1) Joe (Employee), 2) Martha (Manager), 3) Bob (VP): "); + var key = Console.ReadKey(); + var userId = key.KeyChar switch + { + '1' => "Joe", + '2' => "Martha", + '3' => "Bob", + _ => null + }; + + Console.Write("\nRun server as 1) Joe (Employee), 2) Martha (Manager), 3) Bob (VP): "); + key = Console.ReadKey(); + SafeLPWSTR serverId = key.KeyChar switch + { + '1' => "Joe", + '2' => "Martha", + '3' => "Bob", + _ => "" + }; + Console.WriteLine(); + + if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(serverId)) + { + Console.WriteLine("Invalid selection. Exiting."); + return; + } + + CreateLocalAcct(userId, pwd); + CreateLocalAcct(serverId!, pwd); + + if (!Impersonate(userId, pwd, out var hClientToken)) + HandleError(GetLastError(), "Impersonate", true, true); + + using var svr = SafeHTHREAD.Create(AuthzSvr, serverId, out _); + + Usage(); + string? input; + while (!string.IsNullOrEmpty(input = Console.ReadLine())) + { + var args = input.Split(' ', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); + try + { + // + // Verify expnese input + // + if (args.Length < 2 || !ExTypes.TryGetValue(args[0], out exBuf.dwType) || !int.TryParse(args[1], out int amt) || amt == 0) + { + Usage(); + continue; + } + + Console.Write($"expense: {ExNames[(int)exBuf.dwType]} Ammount: {exBuf.dwAmmount}\n"); + + var szPipeName = $"{szServerName}\\pipe\\AuthzSamplePipe"; + + // Wait for an instance of the pipe + if (!WaitNamedPipe(szPipeName, NMPWAIT_WAIT_FOREVER)) + HandleError(GetLastError(), "WaitNamedPipe", true, true); + + // Connect to pipe + using var hPipe = CreateFile(szPipeName, FileAccess.GENERIC_READ | FileAccess.GENERIC_WRITE, 0, + default, CreationOption.OPEN_EXISTING, 0, default); + if (hPipe.IsInvalid) + HandleError(GetLastError(), "CreateFile", true, true); + + // Send off request + WriteToPipe(hPipe, exBuf); + + // wait till server responds with one uint + if (ReadFromPipe(hPipe, out uint dwResponse) == 0) + { + Console.Write("Error reading form Svr\n"); + return; + } + + switch (dwResponse) + { + case EXPENSE_APPROVED: + Console.Write("Expense Approved.\n"); + break; + + case Win32Error.ERROR_ACCESS_DENIED: + Console.Write("Expense denied: Access denied.\n"); + break; + + case ERROR_INSUFFICIENT_FUNDS: + Console.Write("Expense denied: Insufficient funds.\n"); + break; + + default: + Console.Write("Expense failed: unexpected error.\n"); + break; + } + } + catch { } + } + svrExit.Set(); + svr.Wait(); + + static void Usage() => Console.Write("Usage: \n"); + } +} \ No newline at end of file diff --git a/Win7Samples/security/authorization/authz/authz.csproj b/Win7Samples/security/authorization/authz/authzclisvr.csproj similarity index 64% rename from Win7Samples/security/authorization/authz/authz.csproj rename to Win7Samples/security/authorization/authz/authzclisvr.csproj index 24c9dca4..8b8abaaa 100644 --- a/Win7Samples/security/authorization/authz/authz.csproj +++ b/Win7Samples/security/authorization/authz/authzclisvr.csproj @@ -6,6 +6,8 @@ + + diff --git a/Win7Samples/security/authorization/authz/authzsvr.cs b/Win7Samples/security/authorization/authz/authzsvr.cs new file mode 100644 index 00000000..24618725 --- /dev/null +++ b/Win7Samples/security/authorization/authz/authzsvr.cs @@ -0,0 +1,484 @@ +using Vanara.InteropServices; +using Vanara.PInvoke; +using static Common; +using static Vanara.PInvoke.AdvApi32; +using static Vanara.PInvoke.Authz; +using static Vanara.PInvoke.Kernel32; + +internal partial class Program +{ + private static uint AuthzSvr(IntPtr ptr) + { + if (!Impersonate(Marshal.PtrToStringUni(ptr)!, pwd, out var hSvrToken)) + HandleError(GetLastError(), "Impersonate", true, true); + + if (!TogglePrivileges(["SeSecurityPrivilege"], true)) + HandleError(GetLastError(), "AdjustTokenPrivileges", true, true); + + using FUNDSRM FundsRM = new(200000000); + + SetupNamedPipe(out SafeHPIPE? hPipe, "\\\\.\\pipe\\AuthzSamplePipe"); + + while (!svrExit.IsSet) + { + // Wait for a client... + + if (!ConnectNamedPipe(hPipe)) + HandleError(GetLastError(), "ConnectNamedPipe", true, true); + + try + { + var dwBytesRead = ReadFromPipe(hPipe, out EX_BUF exBuf); + if (dwBytesRead == 0) + Console.Write("Error reading from client\n"); + + // Get Token + + if (!ImpersonateNamedPipeClient(hPipe)) + HandleError(GetLastError(), "ImpersonateNamedPipeClient", true, true); + + if (!GetUserName(out var ClientName)) + HandleError(GetLastError(), "GetUserName", true, true); + + if (!OpenThreadToken(GetCurrentThread(), TokenAccess.TOKEN_QUERY | TokenAccess.TOKEN_IMPERSONATE, false, out SafeHTOKEN? hToken)) + HandleError(GetLastError(), "OpenThreadToken", true, true); + + using (hToken) + { + RevertToSelf(); + + Console.Write($"{ClientName} requests {ExNames[(int)exBuf.dwType]} expense of {exBuf.dwAmmount} cents\n"); + + // use token to and context to vaidate - note that this sample uses the token if we just had a user's sid we could build + // an authz context with that. + + if (!FundsRM.AuthorizeAndExecuteExpense(hToken, exBuf, out Win32Error dwResult)) + { + Console.Write($"Error executing expense: {dwResult}\n"); + } + + WriteToPipe(hPipe, dwResult); + } + } + finally + { + DisconnectNamedPipe(hPipe); + } + } + + return 0; + } + + // + // Routine Description: + // Attempts to enable or disable a given privilege. Returns the previous state for the privilege. + // + private static bool TogglePrivileges(string[] privilegeNames, bool enable) + { + using SafeHTOKEN token = SafeHTOKEN.FromThread(GetCurrentThread(), TokenAccess.TOKEN_ADJUST_PRIVILEGES | TokenAccess.TOKEN_QUERY); + var newPriv = new TOKEN_PRIVILEGES(Array.ConvertAll(privilegeNames, s => new LUID_AND_ATTRIBUTES(LUID.FromName(s), enable ? PrivilegeAttributes.SE_PRIVILEGE_ENABLED : 0))); + return AdjustTokenPrivileges(token, false, newPriv, out _).Succeeded; + } +} + +// struct that maintains the state of the fund +internal class FUNDSRM : IDisposable +{ + private const uint MaxSpendingEmployee = 50000; + private const uint MaxSpendingManager = 1000000; + private const uint MaxSpendingVP = 100000000; + + // The amount of money available in the fund + public uint dwFundsAvailable; + + // The resource manager, initialized with the callback functions + public SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM; + + // The security descriptor for the fund, containing a callback ACE which causes the resource manager callbacks to be used + public SafePSECURITY_DESCRIPTOR SD; + + private static readonly SafePSID EmployeeSid = new([0x00, 0x00, 0x05, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x17, 0xb8, 0x51, 0x59, 0x25, 0x5d, 0x72, 0x66, 0x0b, 0x3b, 0x63, 0x64, 0x00, 0x01, 0x00, 0x03]); + private static readonly SafePSID ManagerSid = new([0x00, 0x00, 0x05, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x17, 0xb8, 0x51, 0x59, 0x25, 0x5d, 0x72, 0x66, 0x0b, 0x3b, 0x63, 0x64, 0x00, 0x01, 0x00, 0x02]); + private static readonly SafePSID VPSid = new([0x00, 0x00, 0x05, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x17, 0xb8, 0x51, 0x59, 0x25, 0x5d, 0x72, 0x66, 0x0b, 0x3b, 0x63, 0x64, 0x00, 0x01, 0x00, 0x01]); + private bool disposedValue; + + public FUNDSRM(uint dwFundsAvailable) + /*++ + + Routine Description + + Initializes the Authz Resource Manager, providing it + with the appropriate callback functions. + It also creates a security descriptor for the fund, allowing only + corporate and transfer expenditures, not personal. Additional logic + could be added to allow VPs to override these restrictions, etc. + + Arguments + + PFUNDSRM pFundsRM - Pointer to a FUNDSRM struct that maintains the state + of the Resource Manager + + uint dwFundsAvailable - The amount of money in the fund managed by this + resource manager + + Return Value + None. + --*/ + { + PSID_IDENTIFIER_AUTHORITY siaWorld = KnownSIDAuthority.SECURITY_WORLD_SID_AUTHORITY; + + // The amount of money in the fund + + this.dwFundsAvailable = dwFundsAvailable; + + // Initialize the fund's resource manager + + if (!AuthzInitializeResourceManager(AuthzResourceManagerFlags.AUTHZ_RM_FLAG_NO_AUDIT | AuthzResourceManagerFlags.AUTHZ_RM_FLAG_INITIALIZE_UNDER_IMPERSONATION, + AuthzAccessCheckCallback, AuthzComputeGroupsCallback, AuthzFreeGroupsCallback, "SampRM", out hRM)) + HandleError(GetLastError(), "AuthzInitializeResourceManager", true, true); + else + Console.Write("Funds Resource Manager initialized - waiting for client\n\n"); + + // Create the fund's security descriptor + + SD = new(Marshal.SizeOf()); + if (!SD.SetGroup(default, false)) + HandleError(GetLastError(), "SetSecurityDescriptorGroup", true, true); + + if (!SD.SetSacl(false, default, false)) + HandleError(GetLastError(), "SetSecurityDescriptorSacl", true, true); + + // an owner must be specified. Since VPs are the highest privileged group this sample we'll make them the owner. + if (!SD.SetOwner(VPSid, false)) + HandleError(GetLastError(), "SetSecurityDescriptorOwner", true, true); + + // Initialize the DACL for the fund + + SafePACL pDaclFund = new(1024, ACL_REVISION_DS); + + // Add an access-allowed ACE for Everyone Only company spending and transfers are allowed for this fund + + // build EVERYONE SID + using (SafePSID psidEveryone = SafePSID.Everyone) + { + using SafePACE pace = new(ACE_TYPE.ACCESS_ALLOWED_CALLBACK_ACE_TYPE, (int)(ACCESS_FUND.ACCESS_FUND_CORPORATE | ACCESS_FUND.ACCESS_FUND_TRANSFER), psidEveryone); + pDaclFund.Add(pace); + } + + // Add that ACL as the security descriptor's DACL + + if (!SD.SetDacl(true, pDaclFund, false)) + HandleError(GetLastError(), "SetSecurityDescriptorDacl", true, true); + } + + ~FUNDSRM() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: false); + } + + public bool AuthorizeAndExecuteExpense(HTOKEN hToken, in EX_BUF exBuf, out Win32Error pdwResult) + /*++ + + Routine Description + + Setups the Authz context and makes call to AuthzAccessCheck. Then + modifies the remaining funds depending on acccess and ammount + + Arguments + + PFUNDSRM pFundsRM - Pointer to a FUNDSRM struct that maintains the state + of the Resource Manager + + HANDLE hToken - The token representing the user were doing the access + check for + + EX_BUF exBuf - struct that contains desired access and expense ammount + + ref uint pdwResult - Pointer to uint to put result/error + + Return Value + bool True if no errors. + --*/ + { + // first we need an Authz context + + if (!AuthzInitializeContextFromToken(0, + hToken, + hRM, + default, + default, + default, + out SafeAUTHZ_CLIENT_CONTEXT_HANDLE? AuthzClient)) + { + HandleError(pdwResult = GetLastError(), "AuthzInitializeContextFromToken", true, false); + return false; + } + + try + { + // Do AccessCheck + AUTHZ_ACCESS_REQUEST AccessRequest = new() + { + DesiredAccess = (int)exBuf.dwType, + PrincipalSelfSid = default, + ObjectTypeList = default, + ObjectTypeListLength = 0, + OptionalArguments = (int)exBuf.dwAmmount, + }; + + // The ResultListLength is set to the number of ObjectType GUIDs in the Request, indicating that the caller would like + // detailed information about granted access to each node in the tree. + AUTHZ_ACCESS_REPLY AccessReply = new(1) + { + GrantedAccessMaskValues = [0], + ErrorValues = [0] + }; + + if (!AuthzAccessCheck(0, + AuthzClient, + AccessRequest, + default, + SD, + default, + 0, + AccessReply, + default)) + { + HandleError(pdwResult = GetLastError(), "AuthzAccessCheck", true, false); + return false; + } + + if ((AccessReply.GrantedAccessMaskValues[0] & (uint)exBuf.dwType) != (uint)exBuf.dwType) + { + // Access is denied get error from reply if there else Getlasterror. + pdwResult = AccessReply.ErrorValues[0]; + Console.Write("Access denied\n\n"); + } + else + { + // Access is granted, is there enough funds, this could have been done within the AuthzAccessCheckCallback but since this + // is more of an execution problem than access checking we'll do it here. + if (dwFundsAvailable < exBuf.dwAmmount) + { + // not enough in ref fund + pdwResult = ERROR_INSUFFICIENT_FUNDS; + Console.Write("Failed : NSF\n\n"); + } + else + { + dwFundsAvailable -= exBuf.dwAmmount; + pdwResult = EXPENSE_APPROVED; + Console.Write("Expense Approved. Remaining funds:{0} cents.\n\n", dwFundsAvailable); + } + } + + return true; + } + finally + { + AuthzClient?.Dispose(); + } + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + } + + hRM.Dispose(); + SD.Dispose(); + disposedValue = true; + } + } + + private static bool AuthzAccessCheckCallback([In] AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, [In] PACE pAce, [In] IntPtr pArgs, ref bool pbAceApplicable) + + /*++ + + Routine Description + + This is the callback access check. It is registered with a + resource manager. AuthzAccessCheck calls this function when it + encounters a callback type ACE, one of: + ACCESS_ALLOWED_CALLBACK_ACE_TYPE + ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE + ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE + + This function determines if the given callback ACE applies to the + client context (which has already had dynamic groups computed) and + the optional arguments, in this case the request amount. + + The list of groups which apply to the user is traversed. If a group + is found which allows the user the requested access, pbAceApplicable + is set to true and the function returns. If the end of the group list + is reached, pbAceApplicable is set to false and the function returns. + + Arguments + + hAuthzClientContext - handle to the AuthzClientContext. + + pAce - pointer to the Ace header. + + pArgs - optional arguments, in this case ref uint , uint is the spending + request amount in cents + + pbAceApplicable - returns true iff the ACE allows the client's request + + Return value + + Bool, true on success, false on error + + --*/ + { + uint dwRequestedSpending = (uint)pArgs.ToInt32(); + + // By default, the ACE does not apply to the request + + pbAceApplicable = false; + + // The object's access mask (right after the ACE_HEADER) The access mask determines types of expenditures allowed from this fund + + //uint pAccessMask = pAce.GetMask(); + + // Get the TOKEN_GROUPS array + + TOKEN_GROUPS pvTokenGroupsBuf; + try { pvTokenGroupsBuf = AuthzGetInformationFromContext(hAuthzClientContext, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoGroupsSids); } + catch { return false; } + + // Go through the groups until end is reached or a group applying to the request is found + + for (int i = 0; i < pvTokenGroupsBuf.GroupCount && pbAceApplicable != true; i++) + { + // This is the business logic. Each level of employee can approve different amounts. + + // VP + + if (VPSid.Equals(pvTokenGroupsBuf.Groups[i].Sid) && dwRequestedSpending <= MaxSpendingVP) + { + pbAceApplicable = true; + } + + // Manager + + if (ManagerSid.Equals(pvTokenGroupsBuf.Groups[i].Sid) && dwRequestedSpending <= MaxSpendingManager) + { + pbAceApplicable = true; + } + + // Employee + + if (EmployeeSid.Equals(pvTokenGroupsBuf.Groups[i].Sid) && dwRequestedSpending <= MaxSpendingEmployee) + { + pbAceApplicable = true; + } + } + + // return true when access check completed (when a callback ace applies not) If we had a runtime error, such as mem alloc errors + // we would return false + return true; + } + + private static bool AuthzComputeGroupsCallback(AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, nint pArgs, out nint pSidAttrArray, out uint pSidCount, out nint pRestrictedSidAttrArray, out uint pRestrictedSidCount) + /*++ + + Routine Description + + Resource manager callback to compute dynamic groups. This is used by the RM + to decide if the specified client context should be included in any RM defined groups. + + In this example, the employees are hardcoded into their roles. However, this is the + place you would normally retrieve data from an external source to determine the + users' additional roles. + + Arguments + + hAuthzClientContext - handle to client context. + Args - optional parameter to pass information for evaluating group membership. + pSidAttrArray - computed group membership SIDs + pSidCount - count of SIDs + pRestrictedSidAttrArray - computed group membership restricted SIDs + pRestrictedSidCount - count of restricted SIDs + + Return Value + + Bool, true for success, false on failure. + + --*/ + { + pSidAttrArray = pRestrictedSidAttrArray = default; + pSidCount = pRestrictedSidCount = 0; + + // First, look up the user's SID from the context + + // Get the SID (inside a TOKEN_USER structure) + + TOKEN_USER pvSidBuf; + try { pvSidBuf = AuthzGetInformationFromContext(hAuthzClientContext, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoUserSid); } + catch { return false; } + + // The hardcoded Sample logic: + // + // Lookup the sid to get the username and grant dynamic sid based on username + // + // Bob is a VP Martha is a Manager Joe is an Employee + + if (!LookupAccountSid(default, pvSidBuf.User.Sid.GetBinaryForm(), out var UserName, out _, out _)) + { + HandleError(GetLastError(), "LookupAccountSid", true, true); + } + + PSID userSid = UserName!.ToLowerInvariant() switch + { + "bob" => VPSid, + "martha" => ManagerSid, + "joe" => EmployeeSid, + _ => PSID.NULL + }; + if (userSid != PSID.NULL) + { + // Allocate the memory for the returns, which will be deallocated by FreeDynamicGroups Only a single group will be returned, + // determining the employee type + + pSidCount = 1; + // No restricted group sids + SafeHGlobalStruct pSidAttrArrayBuf = new SID_AND_ATTRIBUTES(userSid, (uint)GroupAttributes.SE_GROUP_ENABLED); + pSidAttrArray = pSidAttrArrayBuf.ReleaseOwnership(); + } + + return true; + } + + private static void AuthzFreeGroupsCallback(nint pSidAttrArray) + /*++ + + Routine Description + + Frees memory allocated for the dynamic group array. + + Arguments + + pSidAttrArray - array to free. + + Return Value + None. + --*/ + { + if (pSidAttrArray != IntPtr.Zero) + { + Marshal.FreeHGlobal(pSidAttrArray); + } + } +} \ No newline at end of file diff --git a/Win7Samples/security/authorization/authz/common.cs b/Win7Samples/security/authorization/authz/common.cs new file mode 100644 index 00000000..e693c230 --- /dev/null +++ b/Win7Samples/security/authorization/authz/common.cs @@ -0,0 +1,227 @@ +using Vanara.Extensions; +using Vanara.InteropServices; +using Vanara.PInvoke; +using static Vanara.PInvoke.AdvApi32; +using static Vanara.PInvoke.Kernel32; +using static Vanara.PInvoke.NetApi32; +//using static Vanara.PInvoke.User32; + +public static class Common +{ + /////////////////////////////////////////////////////////////////////////////// + // Access flags for funds RM + // + /////////////////////////////////////////////////////////////////////////////// + + // + // Expense failed insufficient funds + // + public const int ERROR_INSUFFICIENT_FUNDS = 0x20000002; + + // + // Expense approved and subtracted from fund. + // + public const int EXPENSE_APPROVED = 0; + + // + // Expense failed due to an unknown error + // + public const int EXPENSE_UNKNOWN_ERROR = 0x20000003; + + // + // Error with bit 29 set are private errors (see SetLastError doc) + // + public const int PRIVATE_ERROR_BIT = 0x20000000; + + public static readonly string[] ExNames = ["", "PERSONAL", "CORPORATE", "", "TRANSFER"]; + + [Flags] + public enum ACCESS_FUND : uint + { + // Personal expenditures + ACCESS_FUND_PERSONAL = 0x00000001, + // Company spending + ACCESS_FUND_CORPORATE = 0x00000002, + // Transfer to other funds + ACCESS_FUND_TRANSFER = 0x00000004, + } + + + /////////////////////////////////////////////////////////////////////////////// + // Codes for expense access attempts + // + /////////////////////////////////////////////////////////////////////////////// + // + // We'll use existing Win32Error.Win32Error.Win32Error.ERROR_ACCESS_DENIED for access denied. + // + // ERROR_ACCESS_DENIED = 0x00000005 + /////////////////////////////////////////////////////////////////////////////// + // Expense request packing struct + // + /////////////////////////////////////////////////////////////////////////////// + + public static bool BuildGenericAccessAcl(out SafePACL ppAcl) + /*++ + + Routine Description + + This function builds a Dacl which grants the creator of the objects + GENERIC_ALL (Full Control) and Everyone GENERIC_READ, GENERIC_WRITE and + GENERIC_EXECUTE access to the object. + + This Dacl allows for higher security than a default Dacl, as this only grants + the creator/owner write access to the security descriptor, and grants + Everyone the ability to "use" the object. This scenario prevents a + malevolent user from disrupting service by preventing arbitrary access + manipulation. + + Arguments + + ref PACL pAcl - Pointer to buffer for pointer to allocated PACL. Must be + freed with LocalFree + + ref uint cbAclSize - Pointer to dword receiving size of acl. + + Return value + + Bool, true on success, false on error + + --*/ + { + // + // build well known sids + // + + // build EVERYONE SID + using SafePSID pEveryoneSid = SafePSID.Everyone; + + // build Creator/Owner SID + AllocateAndInitializeSid(KnownSIDAuthority.SECURITY_CREATOR_SID_AUTHORITY, 1, KnownSIDRelativeID.SECURITY_CREATOR_OWNER_RID, 0, 0, 0, 0, 0, 0, 0, out var pOwnerSid); + + ppAcl = new SafePACL([ + new SafePACE(ACE_TYPE.ACCESS_ALLOWED_ACE_TYPE, ACCESS_MASK.GENERIC_READ | ACCESS_MASK.GENERIC_WRITE | ACCESS_MASK.GENERIC_EXECUTE, pEveryoneSid), + new SafePACE(ACE_TYPE.ACCESS_ALLOWED_ACE_TYPE, ACCESS_MASK.GENERIC_ALL, pOwnerSid), + ]); + + return true; + } + + public static bool CreateLocalAcct(string pszName, string pszPassword, UserPrivilege priv = UserPrivilege.USER_PRIV_USER, UserAcctCtrlFlags flags = 0) + { + USER_INFO_1 ui = new() { usri1_name = pszName, usri1_password = pszPassword, usri1_priv = priv, usri1_flags = flags }; + try { NetUserAdd(null, ui); return true; } catch (Exception ex) { return ex.HResult == ((Win32Error)Win32Error.NERR_UserExists).ToHRESULT(); } + } + + public static bool Impersonate(string pszName, string pszPassword, out SafeHTOKEN hToken) + { + if (!LogonUser(pszName, ".", pszPassword, LogonUserType.LOGON32_LOGON_INTERACTIVE, LogonUserProvider.LOGON32_PROVIDER_DEFAULT, out hToken)) + return false; + return ImpersonateLoggedOnUser(hToken); + } + + ////////////////////////////////////////////////////////////////////// + public static Win32Error DisplayAPIError(string pszAPI, bool bConsole, bool bMsgBox, bool bExit) + { + var dwError = Win32Error.GetLastError(); + + //... now display this string + var szErrMsgBuffer = $"ERROR: API = {pszAPI}.\nERROR CODE = {(uint)dwError} (0x{(uint)dwError:X}).\nMESSAGE = {dwError}"; + + if (bConsole) + Console.Write(szErrMsgBuffer); + //if (bMsgBox) + // MessageBox(GetDesktopWindow(), szErrMsgBuffer, "Execution Error", MB_FLAGS.MB_OK); + + OutputDebugString(szErrMsgBuffer); + + if (bExit) + ExitProcess((uint)dwError); + + return dwError; + } + + public static void HandleError(Win32Error dwErr, string pszAPI, bool fAPI, bool fExit) + { + if (fAPI) + { + DisplayAPIError(pszAPI, true, true, fExit); + } + else + { + Console.Write(pszAPI); + if (dwErr.Failed) + Console.Write($"{(uint)dwErr}\n"); + + if (fExit) + ExitProcess(0); + } + + return; + } + + public static uint ReadFromPipe(HFILE hPipe, out T pBuffer) where T : struct + { + var bRet = ReadFile(hPipe, out pBuffer); + if (!bRet) + { + var dwErr = GetLastError(); + // if ERROR_BROKEN_PIPE or ERROR_NO_DATA then pipe naturally ended + if ((uint)dwErr is not (Win32Error.ERROR_BROKEN_PIPE or Win32Error.ERROR_NO_DATA)) + HandleError(dwErr, "ReadFile", true, true); + } + + return InteropExtensions.SizeOf(); + } + + public static bool SetupNamedPipe(out SafeHPIPE phPipe, string szPipeName) + { + phPipe = SafeHPIPE.Null; + SafePSECURITY_DESCRIPTOR sd = new(Marshal.SizeOf()); + + if (!BuildGenericAccessAcl(out var pDacl)) + { + HandleError(0, "Error setting up pipe dacl", false, true); + return false; + } + + if (!sd.SetDacl(true, pDacl, false)) + { + HandleError(GetLastError(), "SetSecurityDescriptorDacl", true, true); + return false; + } + + SECURITY_ATTRIBUTES sa = new() { lpSecurityDescriptor = sd }; + + // setup pipe and wait for a ref connection + phPipe = CreateNamedPipe(szPipeName, PIPE_ACCESS.FILE_FLAG_OVERLAPPED | PIPE_ACCESS.PIPE_ACCESS_DUPLEX, + PIPE_TYPE.PIPE_TYPE_MESSAGE | PIPE_TYPE.PIPE_READMODE_MESSAGE | PIPE_TYPE.PIPE_WAIT, 1, 0, 0, + NMPWAIT_USE_DEFAULT_WAIT, sa); + if (phPipe.IsInvalid) + { + HandleError(GetLastError(), "CreateNamedPipe", true, true); + return false; + } + + return true; + } + + public static bool WriteToPipe(HFILE hPipe, T pData) where T : struct + { + using var pDataBuffer = SafeHGlobalHandle.CreateFromStructure(pData); + var bRet = WriteFile(hPipe, pDataBuffer, (uint)pDataBuffer.Size, out var nBytesWrote); + if (!bRet) + { + var dwErr = GetLastError(); + // if ERROR_BROKEN_PIPE or ERROR_NO_DATA then pipe naturally ended + if ((uint)dwErr is not (Win32Error.ERROR_BROKEN_PIPE or Win32Error.ERROR_NO_DATA)) + HandleError(dwErr, "WriteFile", true, true); + } + return bRet; + } + + public struct EX_BUF + { + public uint dwAmmount; + public ACCESS_FUND dwType; + } +} \ No newline at end of file diff --git a/Win7Samples/security/authorization/klist/klist.cs b/Win7Samples/security/authorization/klist/klist.cs index 6f519c03..efcd4342 100644 --- a/Win7Samples/security/authorization/klist/klist.cs +++ b/Win7Samples/security/authorization/klist/klist.cs @@ -125,7 +125,7 @@ static bool PurgeTicket(SafeLsaConnectionHandle LogonHandle, uint PackageId, str Console.Write("\t RealmName = {0}\n", CacheRequest.RealmName); using var pin = new PinnedObject(CacheRequest); - var Status = LsaCallAuthenticationPackage(LogonHandle, PackageId, pin, (uint)Marshal.SizeOf(typeof(KERB_PURGE_TKT_CACHE_REQUEST)), out _, out _, out var SubStatus); + var Status = LsaCallAuthenticationPackage(LogonHandle, PackageId, pin, (uint)Marshal.SizeOf(), out _, out _, out var SubStatus); if (Status.Failed || SubStatus.Failed) { @@ -240,7 +240,7 @@ static bool GetEncodedTicket(SafeLsaConnectionHandle LogonHandle, uint PackageId var CacheRequest = new KERB_RETRIEVE_TKT_REQUEST { MessageType = KERB_PROTOCOL_MESSAGE_TYPE.KerbRetrieveEncodedTicketMessage, TargetName = Target }; using var pin = new PinnedObject(CacheRequest); - var Status = LsaCallAuthenticationPackage(LogonHandle, PackageId, pin, (uint)Marshal.SizeOf(typeof(KERB_RETRIEVE_TKT_REQUEST)), out var mem, out var ResponseSize, out var SubStatus); + var Status = LsaCallAuthenticationPackage(LogonHandle, PackageId, pin, (uint)Marshal.SizeOf(), out var mem, out var ResponseSize, out var SubStatus); if (Status.Failed || SubStatus.Failed) { diff --git a/Win7Samples/security/authorization/secprint/secprint.cs b/Win7Samples/security/authorization/secprint/secprint.cs index 23b29057..37d12623 100644 --- a/Win7Samples/security/authorization/secprint/secprint.cs +++ b/Win7Samples/security/authorization/secprint/secprint.cs @@ -186,13 +186,13 @@ unsafe static bool AddAccessRights(string szPrinterName, uint dwAccessMask, AceF if (!pACL.IsInvalid && AclInfo is not null) // Add room for new ACEs { dwNewACLSize = (int)AclInfo.Value.AclBytesInUse + - Marshal.SizeOf(typeof(ACCESS_ALLOWED_ACE)) + + Marshal.SizeOf() + GetLengthSid(pSid) - sizeof(uint); } else { - dwNewACLSize = Marshal.SizeOf(typeof(ACCESS_ALLOWED_ACE)) + - Marshal.SizeOf(typeof(ACL)) + + dwNewACLSize = Marshal.SizeOf() + + Marshal.SizeOf() + GetLengthSid(pSid) - sizeof(uint); } } diff --git a/Win7Samples/security/cryptoapi/CertSelect/CertSelect.cs b/Win7Samples/security/cryptoapi/CertSelect/CertSelect.cs index 219f8abe..c23aa295 100644 --- a/Win7Samples/security/cryptoapi/CertSelect/CertSelect.cs +++ b/Win7Samples/security/cryptoapi/CertSelect/CertSelect.cs @@ -105,7 +105,7 @@ static unsafe int Main() { var CredUiInfo = new CREDUI_INFO { - cbSize = Marshal.SizeOf(typeof(CREDUI_INFO)), + cbSize = Marshal.SizeOf(), pszCaptionText = "Select your credentials", pszMessageText = "Please select a certificate" }; diff --git a/Win7Samples/security/cryptoapi/encryptmessage/cms_encrypt.cs b/Win7Samples/security/cryptoapi/encryptmessage/cms_encrypt.cs index 17352d3b..06ddd049 100644 --- a/Win7Samples/security/cryptoapi/encryptmessage/cms_encrypt.cs +++ b/Win7Samples/security/cryptoapi/encryptmessage/cms_encrypt.cs @@ -275,7 +275,7 @@ static int Main(string[] args) var EncryptParams = new CRYPT_ENCRYPT_MESSAGE_PARA { - cbSize = (uint)Marshal.SizeOf(typeof(CRYPT_ENCRYPT_MESSAGE_PARA)), + cbSize = (uint)Marshal.SizeOf(), dwMsgEncodingType = CertEncodingType.X509_ASN_ENCODING | CertEncodingType.PKCS_7_ASN_ENCODING }; @@ -314,7 +314,7 @@ static int Main(string[] args) { var DecryptParams = new CRYPT_DECRYPT_MESSAGE_PARA { - cbSize = (uint)Marshal.SizeOf(typeof(CRYPT_DECRYPT_MESSAGE_PARA)), + cbSize = (uint)Marshal.SizeOf(), dwMsgAndCertEncodingType = CertEncodingType.X509_ASN_ENCODING | CertEncodingType.PKCS_7_ASN_ENCODING, cCertStore = 1, rghCertStore = pphStoreHandle diff --git a/Win7Samples/security/cryptoapi/enumalgs/EnumAlgs.cs b/Win7Samples/security/cryptoapi/enumalgs/EnumAlgs.cs index 26c0d54a..e97f1c94 100644 --- a/Win7Samples/security/cryptoapi/enumalgs/EnumAlgs.cs +++ b/Win7Samples/security/cryptoapi/enumalgs/EnumAlgs.cs @@ -23,7 +23,7 @@ static void Main() uint dwFlags = 1; // CRYPT_FIRST // Set size of data expected - var dwDataLen = (uint)Marshal.SizeOf(typeof(PROV_ENUMALGS)); + var dwDataLen = (uint)Marshal.SizeOf(); // Enumerate the supported algorithms. while (true) diff --git a/Win7Samples/web/Wininet/async/Program.cs b/Win7Samples/web/Wininet/async/Program.cs index 4ec0ae3c..152603cc 100644 --- a/Win7Samples/web/Wininet/async/Program.cs +++ b/Win7Samples/web/Wininet/async/Program.cs @@ -226,7 +226,7 @@ public static int Main(string[] args) //Prepare the Buffers to be passed to HttpSendRequestEx INTERNET_BUFFERS buffersIn = new() { - dwStructSize = (uint)Marshal.SizeOf(typeof(INTERNET_BUFFERS)), + dwStructSize = (uint)Marshal.SizeOf(), dwBufferTotal = dwFileSize //content-length of data to post }; @@ -299,7 +299,7 @@ static void CallBack(HINTERNET hInternet, IntPtr dwContext, InternetStatus dwInt Console.Error.Write("Status: Cookie History\n"); //Verify we've a valid pointer with the correct size - if (lpvStatusInformation != default && dwStatusInformationLength == Marshal.SizeOf(typeof(InternetCookieHistory))) + if (lpvStatusInformation != default && dwStatusInformationLength == Marshal.SizeOf()) { cookieHistory = lpvStatusInformation.ToStructure(dwStatusInformationLength); } @@ -363,7 +363,7 @@ static void CallBack(HINTERNET hInternet, IntPtr dwContext, InternetStatus dwInt break; case InternetStatus.INTERNET_STATUS_RESPONSE_RECEIVED: //Verify we've a valid pointer with the correct size - if (lpvStatusInformation != default && dwStatusInformationLength == Marshal.SizeOf(typeof(uint))) + if (lpvStatusInformation != default && dwStatusInformationLength == Marshal.SizeOf()) { dwBytes = lpvStatusInformation.ToStructure(); Console.Error.Write("Status: Response Received ({0} Bytes)\n", dwBytes); @@ -462,7 +462,7 @@ static void CallBack(HINTERNET hInternet, IntPtr dwContext, InternetStatus dwInt break; case InternetStatus.INTERNET_STATUS_REQUEST_SENT: //Verify we've a valid pointer with the correct size - if (lpvStatusInformation != default && dwStatusInformationLength == Marshal.SizeOf(typeof(uint))) + if (lpvStatusInformation != default && dwStatusInformationLength == Marshal.SizeOf()) { dwBytes = lpvStatusInformation.ToStructure(); Console.Error.Write("Status: Request sent ({0} Bytes)\n", dwBytes); diff --git a/Win7Samples/web/winhttp/WinHttpPostSample/Program.cs b/Win7Samples/web/winhttp/WinHttpPostSample/Program.cs index 472fea48..7ba61df1 100644 --- a/Win7Samples/web/winhttp/WinHttpPostSample/Program.cs +++ b/Win7Samples/web/winhttp/WinHttpPostSample/Program.cs @@ -43,7 +43,7 @@ static int Main(string[] args) WINHTTP_URL_COMPONENTS urlComponents = new() { - dwStructSize = (uint)Marshal.SizeOf(typeof(WINHTTP_URL_COMPONENTS)), + dwStructSize = (uint)Marshal.SizeOf(), dwUserNameLength = 1, dwPasswordLength = 1, dwHostNameLength = 1, @@ -59,7 +59,7 @@ static int Main(string[] args) urlComponents = new() { - dwStructSize = (uint)Marshal.SizeOf(typeof(WINHTTP_URL_COMPONENTS)), + dwStructSize = (uint)Marshal.SizeOf(), dwUserNameLength = 1, dwPasswordLength = 1, dwHostNameLength = 1, @@ -205,7 +205,7 @@ static bool WinHttpSamplePost(string szServerUrl, string szFile, string? szProxy // From the server URL, we need a host, path, username and password. WINHTTP_URL_COMPONENTS urlServerComponents = new() { - dwStructSize = (uint)Marshal.SizeOf(typeof(WINHTTP_URL_COMPONENTS)), + dwStructSize = (uint)Marshal.SizeOf(), dwHostNameLength = 1, dwUrlPathLength = 1, dwUserNameLength = 1, @@ -242,7 +242,7 @@ static bool WinHttpSamplePost(string szServerUrl, string szFile, string? szProxy // From the proxy URL, we need a host, username and password. WINHTTP_URL_COMPONENTS urlProxyComponents = new() { - dwStructSize = (uint)Marshal.SizeOf(typeof(WINHTTP_URL_COMPONENTS)), + dwStructSize = (uint)Marshal.SizeOf(), dwHostNameLength = 1, dwUserNameLength = 1, dwPasswordLength = 1 diff --git a/Win7Samples/web/winhttp/WinhttpAsyncSample/Program.cs b/Win7Samples/web/winhttp/WinhttpAsyncSample/Program.cs index afeabfce..89a0e6ba 100644 --- a/Win7Samples/web/winhttp/WinhttpAsyncSample/Program.cs +++ b/Win7Samples/web/winhttp/WinhttpAsyncSample/Program.cs @@ -417,7 +417,7 @@ private static Win32Error OnHeadersAvailable(MYCONTEXT pContext) _ = Win32Error.ERROR_SUCCESS; WINHTTP_QUERY dwFlags = WINHTTP_QUERY.WINHTTP_QUERY_FLAG_NUMBER | WINHTTP_QUERY.WINHTTP_QUERY_STATUS_CODE; uint StatusCode; - _ = Marshal.SizeOf(typeof(uint)); + _ = Marshal.SizeOf(); Console.Write("OnHeadersAvailable\n"); Win32Error dwError; diff --git a/Win7Samples/winbase/imapi/IBurn/IMAPIv2Extensions.cs b/Win7Samples/winbase/imapi/IBurn/IMAPIv2Extensions.cs index 3280d231..72767197 100644 --- a/Win7Samples/winbase/imapi/IBurn/IMAPIv2Extensions.cs +++ b/Win7Samples/winbase/imapi/IBurn/IMAPIv2Extensions.cs @@ -264,7 +264,7 @@ public static HRESULT GetPhysicalDvdStructure(this IDiscRecorder2Ex recorder, ou { // Read the DVD structure recorder.ReadDvdStructure(0, 0, 0, 0, out var tmpDescriptor, out var tmpDescriptorSize); - if (tmpDescriptorSize < Marshal.SizeOf(typeof(DVD_LAYER_DESCRIPTOR))) + if (tmpDescriptorSize < Marshal.SizeOf()) return HRESULT.E_IMAPI_RECORDER_INVALID_RESPONSE_FROM_DEVICE; // save the results diff --git a/Win7Samples/winbase/imapi/IBurn/OpticalStorage.cs b/Win7Samples/winbase/imapi/IBurn/OpticalStorage.cs index 5eb3bc80..32461ee1 100644 --- a/Win7Samples/winbase/imapi/IBurn/OpticalStorage.cs +++ b/Win7Samples/winbase/imapi/IBurn/OpticalStorage.cs @@ -2735,7 +2735,7 @@ internal WriteSpeedDescriptor(IWriteSpeedDescriptor desc) internal class AudioFile : ComFileStream { - private static readonly int hdrSize = Marshal.SizeOf(typeof(WAV_HEADER)); + private static readonly int hdrSize = Marshal.SizeOf(); private const long SECTOR_SIZE = 2352; public AudioFile(string fileName) diff --git a/Win7Samples/winui/magnificiation/Program.cs b/Win7Samples/winui/magnificiation/Program.cs index e588157f..8a2b2c3c 100644 --- a/Win7Samples/winui/magnificiation/Program.cs +++ b/Win7Samples/winui/magnificiation/Program.cs @@ -150,7 +150,7 @@ ATOM RegisterHostWindowClass() { WNDCLASSEX wcex = new() { - cbSize = (uint)Marshal.SizeOf(typeof(WNDCLASSEX)), + cbSize = (uint)Marshal.SizeOf(), style = WindowClassStyles.CS_HREDRAW | WindowClassStyles.CS_VREDRAW, lpfnWndProc = HostWndProc, hInstance = hInst, diff --git a/Win7Samples/winui/shell/appplatform/DragDropVisuals/DragDropVisualsRes.dll b/Win7Samples/winui/shell/appplatform/DragDropVisuals/DragDropVisualsRes.dll index 6bda98c7..d3eb6a78 100644 Binary files a/Win7Samples/winui/shell/appplatform/DragDropVisuals/DragDropVisualsRes.dll and b/Win7Samples/winui/shell/appplatform/DragDropVisuals/DragDropVisualsRes.dll differ diff --git a/Win7Samples/winui/shell/appplatform/DragDropVisuals/ShellHelpers.cs b/Win7Samples/winui/shell/appplatform/DragDropVisuals/ShellHelpers.cs index fb651c16..7a4be37f 100644 --- a/Win7Samples/winui/shell/appplatform/DragDropVisuals/ShellHelpers.cs +++ b/Win7Samples/winui/shell/appplatform/DragDropVisuals/ShellHelpers.cs @@ -90,7 +90,7 @@ public static void SafeRelease(ref T? ppT) where T : class // HICON that is created public static void SetDialogIcon(HWND hdlg, SHSTOCKICONID siid) { - SHSTOCKICONINFO sii = new() { cbSize = (uint)Marshal.SizeOf(typeof(SHSTOCKICONINFO)) }; + SHSTOCKICONINFO sii = new() { cbSize = (uint)Marshal.SizeOf() }; if (SHGetStockIconInfo(siid, SHGSI.SHGSI_ICON | SHGSI.SHGSI_SMALLICON, ref sii).Succeeded) { SendMessage(hdlg, WindowMessage.WM_SETICON, WM_ICON_WPARAM.ICON_SMALL, (IntPtr)sii.hIcon); @@ -149,7 +149,7 @@ public static HRESULT ShellExecuteItem(HWND hwnd, string? pszVerb, IShellItem ps { SHELLEXECUTEINFO ei = new() { - cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO)), + cbSize = Marshal.SizeOf(), fMask = ShellExecuteMaskFlags.SEE_MASK_INVOKEIDLIST, hwnd = hwnd, nShellExecuteShow = ShowWindowCommand.SW_NORMAL, diff --git a/Win7Samples/winui/shell/appplatform/ExplorerBrowserSearch/ShellHelpers.cs b/Win7Samples/winui/shell/appplatform/ExplorerBrowserSearch/ShellHelpers.cs index a11865cc..cf1d148a 100644 --- a/Win7Samples/winui/shell/appplatform/ExplorerBrowserSearch/ShellHelpers.cs +++ b/Win7Samples/winui/shell/appplatform/ExplorerBrowserSearch/ShellHelpers.cs @@ -71,7 +71,7 @@ public static bool ShellExecuteItem(this IShellItem psi, string? pszVerb = null, var ei = new SHELLEXECUTEINFO { - cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO)), + cbSize = Marshal.SizeOf(), fMask = ShellExecuteMaskFlags.SEE_MASK_INVOKEIDLIST, hwnd = hwnd, nShellExecuteShow = ShowWindowCommand.SW_NORMAL, diff --git a/Win7Samples/winui/shell/appplatform/FIleOperationProgressSink/ProgressSinkSampleAppRes.dll b/Win7Samples/winui/shell/appplatform/FIleOperationProgressSink/ProgressSinkSampleAppRes.dll index 05bcd847..69eb0d10 100644 Binary files a/Win7Samples/winui/shell/appplatform/FIleOperationProgressSink/ProgressSinkSampleAppRes.dll and b/Win7Samples/winui/shell/appplatform/FIleOperationProgressSink/ProgressSinkSampleAppRes.dll differ diff --git a/Win7Samples/winui/shell/appplatform/NamespaceTreeControl/NameSpaceTreeSample.cs b/Win7Samples/winui/shell/appplatform/NamespaceTreeControl/NameSpaceTreeSample.cs index b2cc8704..857073a5 100644 --- a/Win7Samples/winui/shell/appplatform/NamespaceTreeControl/NameSpaceTreeSample.cs +++ b/Win7Samples/winui/shell/appplatform/NamespaceTreeControl/NameSpaceTreeSample.cs @@ -63,7 +63,7 @@ private static void ClearDialogIcon(HWND hdlg) private static void SetDialogIcon(HWND hdlg, SHSTOCKICONID siid) { - SHSTOCKICONINFO sii = new() { cbSize = (uint)Marshal.SizeOf(typeof(SHSTOCKICONINFO)) }; + SHSTOCKICONINFO sii = new() { cbSize = (uint)Marshal.SizeOf() }; if (SHGetStockIconInfo(siid, SHGSI.SHGSI_ICON | SHGSI.SHGSI_SMALLICON, ref sii).Succeeded) { SendMessage(hdlg, WindowMessage.WM_SETICON, WM_ICON_WPARAM.ICON_SMALL, (IntPtr)sii.hIcon); @@ -481,7 +481,7 @@ private void OnOpen() { SHELLEXECUTEINFO ei = new() { - cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO)), + cbSize = Marshal.SizeOf(), fMask = ShellExecuteMaskFlags.SEE_MASK_INVOKEIDLIST, hwnd = hdlg, nShellExecuteShow = ShowWindowCommand.SW_NORMAL, diff --git a/Win7Samples/winui/shell/appplatform/NamespaceTreeControl/NamespaceTreeSDKSampleRes.dll b/Win7Samples/winui/shell/appplatform/NamespaceTreeControl/NamespaceTreeSDKSampleRes.dll index d2e5451f..95e1c99f 100644 Binary files a/Win7Samples/winui/shell/appplatform/NamespaceTreeControl/NamespaceTreeSDKSampleRes.dll and b/Win7Samples/winui/shell/appplatform/NamespaceTreeControl/NamespaceTreeSDKSampleRes.dll differ diff --git a/Win7Samples/winui/shell/appplatform/ParsingWithParameters/ParsingWithParameters.cs b/Win7Samples/winui/shell/appplatform/ParsingWithParameters/ParsingWithParameters.cs index 1e268e4f..ce5a7ce4 100644 --- a/Win7Samples/winui/shell/appplatform/ParsingWithParameters/ParsingWithParameters.cs +++ b/Win7Samples/winui/shell/appplatform/ParsingWithParameters/ParsingWithParameters.cs @@ -47,7 +47,7 @@ private static IBindCtx CreateFileSysBindCtx(in WIN32_FIND_DATA pfd) { var pfsbd = new CFileSysBindData(pfd); CreateBindCtx(0, out var pbc).ThrowIfFailed(); - var bo = new BIND_OPTS { cbStruct = Marshal.SizeOf(typeof(BIND_OPTS)), grfMode = (int)STGM.STGM_CREATE }; + var bo = new BIND_OPTS { cbStruct = Marshal.SizeOf(), grfMode = (int)STGM.STGM_CREATE }; pbc!.SetBindOptions(ref bo); pbc.RegisterObjectParam(STR_FILE_SYS_BIND_DATA, pfsbd); return pbc; diff --git a/Win7Samples/winui/shell/appplatform/ShellLibraryBackup/ShellLibraryBackup.cs b/Win7Samples/winui/shell/appplatform/ShellLibraryBackup/ShellLibraryBackup.cs index 062401ca..23816001 100644 --- a/Win7Samples/winui/shell/appplatform/ShellLibraryBackup/ShellLibraryBackup.cs +++ b/Win7Samples/winui/shell/appplatform/ShellLibraryBackup/ShellLibraryBackup.cs @@ -210,7 +210,7 @@ private static void Main() // Create the main page of the wizard PROPSHEETPAGE psp = new() { - dwSize = (uint)Marshal.SizeOf(typeof(PROPSHEETPAGE)), + dwSize = (uint)Marshal.SizeOf(), dwFlags = PropSheetFlags.PSP_USEHEADERTITLE, hInstance = g_hinst, pszTemplate = IDD_MainPage, @@ -240,7 +240,7 @@ private static void Main() { PROPSHEETHEADER psh = new() { - dwSize = (uint)Marshal.SizeOf(typeof(PROPSHEETHEADER)), + dwSize = (uint)Marshal.SizeOf(), dwFlags = PropSheetHeaderFlags.PSH_AEROWIZARD | PropSheetHeaderFlags.PSH_WIZARD, hInstance = g_hinst, nPages = (uint)rhpsp.Count, diff --git a/Win7Samples/winui/shell/appplatform/ShellLibraryBackup/ShellLibraryBackupRes.dll b/Win7Samples/winui/shell/appplatform/ShellLibraryBackup/ShellLibraryBackupRes.dll index 1f7308e6..37792f7a 100644 Binary files a/Win7Samples/winui/shell/appplatform/ShellLibraryBackup/ShellLibraryBackupRes.dll and b/Win7Samples/winui/shell/appplatform/ShellLibraryBackup/ShellLibraryBackupRes.dll differ diff --git a/Win7Samples/winui/shell/appplatform/ShellStorage/ShellStorage.cs b/Win7Samples/winui/shell/appplatform/ShellStorage/ShellStorage.cs index e720cb34..e68e825e 100644 --- a/Win7Samples/winui/shell/appplatform/ShellStorage/ShellStorage.cs +++ b/Win7Samples/winui/shell/appplatform/ShellStorage/ShellStorage.cs @@ -38,7 +38,7 @@ private static void CreateFolderInContainer(IShellItem psi, string pszFolderName private static IBindCtx CreateBindCtxWithMode(STGM grfMode) { CreateBindCtx(0, out var ppbc).ThrowIfFailed(); - BIND_OPTS boptions = new() { cbStruct = Marshal.SizeOf(typeof(BIND_OPTS)), grfMode = (int)grfMode }; + BIND_OPTS boptions = new() { cbStruct = Marshal.SizeOf(), grfMode = (int)grfMode }; ppbc!.SetBindOptions(ref boptions); return ppbc; } diff --git a/Win7Samples/winui/shell/legacysamples/fakemenu/Program.cs b/Win7Samples/winui/shell/legacysamples/fakemenu/Program.cs index f71cf638..05d1c0a4 100644 --- a/Win7Samples/winui/shell/legacysamples/fakemenu/Program.cs +++ b/Win7Samples/winui/shell/legacysamples/fakemenu/Program.cs @@ -451,7 +451,7 @@ static void ColorPick_ChooseLocation(HWND hwnd, int x, int y, int cx, int cy, ou hmon = MonitorFromWindow(hwnd, MonitorFlags.MONITOR_DEFAULTTONEAREST); } - MONITORINFO minf = new() { cbSize = (uint)Marshal.SizeOf(typeof(MONITORINFO)) }; + MONITORINFO minf = new() { cbSize = (uint)Marshal.SizeOf() }; GetMonitorInfo(hmon, ref minf); // Now slide things around until they fit. diff --git a/Win7Samples/winui/shell/shellextensibility/explorerdataprovider/ExplorerDataProvider.cs b/Win7Samples/winui/shell/shellextensibility/explorerdataprovider/ExplorerDataProvider.cs index 41afb852..1b94e30c 100644 --- a/Win7Samples/winui/shell/shellextensibility/explorerdataprovider/ExplorerDataProvider.cs +++ b/Win7Samples/winui/shell/shellextensibility/explorerdataprovider/ExplorerDataProvider.cs @@ -298,7 +298,7 @@ public HRESULT CreateViewObject(HWND hwndOwner, in Guid riid, out object? ppv) HRESULT hr = HRESULT.E_NOINTERFACE; if (riid == typeof(IShellView).GUID) { - SFV_CREATE csfv = new() { cbSize = (uint)Marshal.SizeOf(typeof(SFV_CREATE)), pshf = this, psfvcb = new CFolderViewCB() }; + SFV_CREATE csfv = new() { cbSize = (uint)Marshal.SizeOf(), pshf = this, psfvcb = new CFolderViewCB() }; hr = SHCreateShellFolderView(csfv, out IShellView? shv); if (hr.Succeeded) ppv = shv; } diff --git a/Win7Samples/winui/speech/SimpleDictation/SimpleDictationRes.dll b/Win7Samples/winui/speech/SimpleDictation/SimpleDictationRes.dll index 266c9a24..84321dbc 100644 Binary files a/Win7Samples/winui/speech/SimpleDictation/SimpleDictationRes.dll and b/Win7Samples/winui/speech/SimpleDictation/SimpleDictationRes.dll differ diff --git a/Win7Samples/winui/speech/SimpleTelephony/SimpleTelephonyRes.dll b/Win7Samples/winui/speech/SimpleTelephony/SimpleTelephonyRes.dll index 92c313cf..b59fe292 100644 Binary files a/Win7Samples/winui/speech/SimpleTelephony/SimpleTelephonyRes.dll and b/Win7Samples/winui/speech/SimpleTelephony/SimpleTelephonyRes.dll differ diff --git a/Win7Samples/winui/speech/TtsApplication/TtsApplicationRes.dll b/Win7Samples/winui/speech/TtsApplication/TtsApplicationRes.dll index 4864fe22..d49f4ada 100644 Binary files a/Win7Samples/winui/speech/TtsApplication/TtsApplicationRes.dll and b/Win7Samples/winui/speech/TtsApplication/TtsApplicationRes.dll differ diff --git a/Win7Samples/winui/speech/TtsApplication/dlgmain.cs b/Win7Samples/winui/speech/TtsApplication/dlgmain.cs index 5e2c900c..06daeb83 100644 --- a/Win7Samples/winui/speech/TtsApplication/dlgmain.cs +++ b/Win7Samples/winui/speech/TtsApplication/dlgmain.cs @@ -532,7 +532,7 @@ bool CallOpenFileDialog(SafeLPTSTR szFileName, string szFilter) var ofn = new OPENFILENAME { - lStructSize = (uint)Marshal.SizeOf(typeof(OPENFILENAME)), + lStructSize = (uint)Marshal.SizeOf(), hwndOwner = Handle, lpstrFilter = szFilter, nFilterIndex = 1, @@ -856,7 +856,7 @@ void MainHandleSynthEvent() } // Highlight word - nStart = (IntPtr)(Stat.ulInputWordPos / Marshal.SizeOf(typeof(byte))); + nStart = (IntPtr)(Stat.ulInputWordPos / Marshal.SizeOf()); nEnd = nStart.Offset(Stat.ulInputWordLen); SendDlgItemMessage(Handle, IDE_EDITBOX, EditMessage.EM_SETSEL, nStart, nEnd); if (IsDlgButtonChecked(Handle, IDC_EVENTS) != 0) diff --git a/Win7Samples/winui/speech/talkback/TalkBackRes.dll b/Win7Samples/winui/speech/talkback/TalkBackRes.dll index f6cd358a..62ba3b48 100644 Binary files a/Win7Samples/winui/speech/talkback/TalkBackRes.dll and b/Win7Samples/winui/speech/talkback/TalkBackRes.dll differ diff --git a/WinClassicSamplesCS.sln b/WinClassicSamplesCS.sln index 47afc02b..97b1ef7a 100644 --- a/WinClassicSamplesCS.sln +++ b/WinClassicSamplesCS.sln @@ -53,7 +53,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "aclapi", "Win7Samples\secur EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "audit", "Win7Samples\security\authorization\audit\audit.csproj", "{B5CB45DC-4DED-4EE2-9242-3F7B0EAEAF58}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "authz", "Win7Samples\security\authorization\authz\authz.csproj", "{86EB6286-8842-4D4C-896B-BB7E5BB5D6D6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "authzclisvr", "Win7Samples\security\authorization\authz\authzclisvr.csproj", "{86EB6286-8842-4D4C-896B-BB7E5BB5D6D6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzMigrate", "Win7Samples\security\authorization\azman\AzMigrate.csproj", "{69DA869D-1797-4417-8102-F02D3AD7C029}" EndProject @@ -775,6 +775,7 @@ Global {4FBDBE52-2844-47F0-8D2E-CA06234E76A8}.Release|x86.ActiveCfg = Release|Any CPU {4FBDBE52-2844-47F0-8D2E-CA06234E76A8}.Release|x86.Build.0 = Release|Any CPU {42D061DF-6C64-4907-B23B-38EAAE1EC701}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42D061DF-6C64-4907-B23B-38EAAE1EC701}.Debug|Any CPU.Build.0 = Debug|Any CPU {42D061DF-6C64-4907-B23B-38EAAE1EC701}.Debug|x64.ActiveCfg = Debug|Any CPU {42D061DF-6C64-4907-B23B-38EAAE1EC701}.Debug|x64.Build.0 = Debug|Any CPU {42D061DF-6C64-4907-B23B-38EAAE1EC701}.Debug|x86.ActiveCfg = Debug|Any CPU diff --git a/WinsockBluetoothConnection/bthcxn.cs b/WinsockBluetoothConnection/bthcxn.cs index 33ea26ce..731cb369 100644 --- a/WinsockBluetoothConnection/bthcxn.cs +++ b/WinsockBluetoothConnection/bthcxn.cs @@ -53,7 +53,7 @@ public struct SOCKADDR_BTH /// RFCOMM channel associated with the socket. See Remarks. public uint port; - public byte[] GetAddressBytes() => ((IntPtr)new PinnedObject(this)).ToArray(Marshal.SizeOf(typeof(SOCKADDR_BTH))) ?? []; + public byte[] GetAddressBytes() => ((IntPtr)new PinnedObject(this)).ToArray(Marshal.SizeOf()) ?? []; public static explicit operator SOCKADDR(SOCKADDR_BTH sblth) => SOCKADDR.CreateFromStructure(sblth); } @@ -241,7 +241,7 @@ static uint NameToBthAddr(string pszRemoteName, out SOCKADDR_BTH RemoteBtAddr) // iResult = CXN_SUCCESS; var bContinueLookup = false; - uint ulPQSSize = (uint)Marshal.SizeOf(typeof(WSAQUERYSET)); + uint ulPQSSize = (uint)Marshal.SizeOf(); iResult = (Win32Error)WSALookupServiceBegin(new WSAQUERYSET(NS.NS_BTH), ulFlags, out var hLookup); // @@ -487,7 +487,7 @@ static uint RunServerMode(int iMaxCxnCycles) // // CSADDR_INFO // - var scktAddr = new SOCKET_ADDRESS { iSockaddrLength = Marshal.SizeOf(typeof(SOCKADDR_BTH)), lpSockaddr = pSockAddrBthLocal }; + var scktAddr = new SOCKET_ADDRESS { iSockaddrLength = Marshal.SizeOf(), lpSockaddr = pSockAddrBthLocal }; var csaddrInfo = new CSADDR_INFO { LocalAddr = scktAddr, @@ -503,7 +503,7 @@ static uint RunServerMode(int iMaxCxnCycles) using var lpCSAddrInfo = SafeCoTaskMemHandle.CreateFromStructure(csaddrInfo); var wsaQuerySet = new WSAQUERYSET { - dwSize = (uint)Marshal.SizeOf(typeof(WSAQUERYSET)), + dwSize = (uint)Marshal.SizeOf(), lpServiceClassId = (IntPtr)pg_guidServiceClass, lpszServiceInstanceName = $"{Environment.MachineName} {CXN_INSTANCE_STRING}", lpszComment = "Example Service instance registered in the directory service through RnR",