mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Clean up calls from win32k to csrss
svn path=/trunk/; revision=9526
This commit is contained in:
parent
63fc502d5a
commit
683ba367cc
15 changed files with 207 additions and 66 deletions
|
@ -162,6 +162,7 @@ NtUserCallNextHookEx(
|
|||
#define NOPARAM_ROUTINE_INIT_MESSAGE_PUMP 0xffff0004
|
||||
#define NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO 0xffff0005
|
||||
#define NOPARAM_ROUTINE_ANYPOPUP 0xffff0006
|
||||
#define NOPARAM_ROUTINE_CSRSS_INITIALIZED 0xffff0007
|
||||
DWORD
|
||||
STDCALL
|
||||
NtUserCallNoParam(
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: misc.c,v 1.4 2004/05/01 16:43:14 weiden Exp $
|
||||
/* $Id: misc.c,v 1.5 2004/05/28 21:33:41 gvg Exp $
|
||||
*
|
||||
* PROJECT: ReactOS user32.dll
|
||||
* FILE: lib/user32/misc/misc.c
|
||||
|
@ -48,7 +48,7 @@ GetGuiResources(
|
|||
|
||||
|
||||
/*
|
||||
* Private call for CSRSS
|
||||
* Private calls for CSRSS
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
|
@ -57,6 +57,13 @@ PrivateCsrssManualGuiCheck(LONG Check)
|
|||
NtUserManualGuiCheck(Check);
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
PrivateCsrssInitialized()
|
||||
{
|
||||
NtUserCallNoParam(NOPARAM_ROUTINE_CSRSS_INITIALIZED);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
|
|
@ -523,6 +523,7 @@ PrintWindow@12
|
|||
PrivateCsrssAcquireOrReleaseInputOwnership@4
|
||||
PrivateCsrssRegisterPrimitive@0
|
||||
PrivateCsrssManualGuiCheck@4
|
||||
PrivateCsrssInitialized@0
|
||||
PrivateExtractIconExA@20
|
||||
PrivateExtractIconExW@20
|
||||
PrivateExtractIconsA@32
|
||||
|
|
|
@ -524,6 +524,7 @@ PrintWindow=PrintWindow@12
|
|||
PrivateCsrssAcquireOrReleaseInputOwnership=PrivateCsrssAcquireOrReleaseInputOwnership@4
|
||||
PrivateCsrssRegisterPrimitive=PrivateCsrssRegisterPrimitive@0
|
||||
PrivateCsrssManualGuiCheck=PrivateCsrssManualGuiCheck@4
|
||||
PrivateCsrssInitialized=PrivateCsrssInitialized@0
|
||||
PrivateExtractIconExA=PrivateExtractIconExA@20
|
||||
PrivateExtractIconExW=PrivateExtractIconExW@20
|
||||
PrivateExtractIconsA=PrivateExtractIconsA@32
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: csrplugin.h,v 1.1 2003/12/02 11:38:46 gvg Exp $
|
||||
/* $Id: csrplugin.h,v 1.2 2004/05/28 21:33:41 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -38,8 +38,11 @@ typedef struct tagCSRSS_EXPORTED_FUNCS
|
|||
CSRSS_RELEASE_OBJECT_PROC CsrReleaseObjectProc;
|
||||
} CSRSS_EXPORTED_FUNCS, *PCSRSS_EXPORTED_FUNCS;
|
||||
|
||||
typedef BOOL STDCALL (*CSRPLUGIN_INITIALIZE_PROC)(PCSRSS_API_DEFINITION *ApiDefinitions,
|
||||
typedef BOOL (STDCALL *CSRPLUGIN_INIT_COMPLETE_PROC)(void);
|
||||
|
||||
typedef BOOL (STDCALL *CSRPLUGIN_INITIALIZE_PROC)(PCSRSS_API_DEFINITION *ApiDefinitions,
|
||||
PCSRSS_OBJECT_DEFINITION *ObjectDefinitions,
|
||||
CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProc,
|
||||
PCSRSS_EXPORTED_FUNCS Exports,
|
||||
HANDLE CsrssApiHeap);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: init.c,v 1.26 2004/04/09 20:03:15 navaraf Exp $
|
||||
/* $Id: init.c,v 1.27 2004/05/28 21:33:41 gvg Exp $
|
||||
*
|
||||
* reactos/subsys/csrss/init.c
|
||||
*
|
||||
|
@ -35,6 +35,53 @@ UNICODE_STRING CsrDirectoryName;
|
|||
|
||||
extern HANDLE CsrssApiHeap;
|
||||
|
||||
static unsigned InitCompleteProcCount;
|
||||
static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL;
|
||||
|
||||
static NTSTATUS FASTCALL
|
||||
AddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
|
||||
{
|
||||
CSRPLUGIN_INIT_COMPLETE_PROC *NewProcs;
|
||||
|
||||
NewProcs = RtlAllocateHeap(CsrssApiHeap, 0,
|
||||
(InitCompleteProcCount + 1)
|
||||
* sizeof(CSRPLUGIN_INIT_COMPLETE_PROC));
|
||||
if (NULL == NewProcs)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
if (0 != InitCompleteProcCount)
|
||||
{
|
||||
RtlCopyMemory(NewProcs, InitCompleteProcs,
|
||||
InitCompleteProcCount * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC));
|
||||
RtlFreeHeap(CsrssApiHeap, 0, InitCompleteProcs);
|
||||
}
|
||||
NewProcs[InitCompleteProcCount] = Proc;
|
||||
InitCompleteProcs = NewProcs;
|
||||
InitCompleteProcCount++;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static BOOL FASTCALL
|
||||
CallInitComplete(void)
|
||||
{
|
||||
BOOL Ok;
|
||||
unsigned i;
|
||||
|
||||
Ok = TRUE;
|
||||
if (0 != InitCompleteProcCount)
|
||||
{
|
||||
for (i = 0; i < InitCompleteProcCount && Ok; i++)
|
||||
{
|
||||
Ok = (*(InitCompleteProcs[i]))();
|
||||
}
|
||||
RtlFreeHeap(CsrssApiHeap, 0, InitCompleteProcs);
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
ULONG
|
||||
InitializeVideoAddressSpace(VOID);
|
||||
|
||||
|
@ -113,6 +160,7 @@ InitWin32Csr()
|
|||
CSRSS_EXPORTED_FUNCS Exports;
|
||||
PCSRSS_API_DEFINITION ApiDefinitions;
|
||||
PCSRSS_OBJECT_DEFINITION ObjectDefinitions;
|
||||
CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc;
|
||||
|
||||
RtlInitUnicodeString(&DllName, L"win32csr.dll");
|
||||
Status = LdrLoadDll(NULL, 0, &DllName, (PVOID *) &hInst);
|
||||
|
@ -129,7 +177,8 @@ InitWin32Csr()
|
|||
Exports.CsrInsertObjectProc = CsrInsertObject;
|
||||
Exports.CsrGetObjectProc = CsrGetObject;
|
||||
Exports.CsrReleaseObjectProc = CsrReleaseObject;
|
||||
if (! (*InitProc)(&ApiDefinitions, &ObjectDefinitions, &Exports, CsrssApiHeap))
|
||||
if (! (*InitProc)(&ApiDefinitions, &ObjectDefinitions, &InitCompleteProc,
|
||||
&Exports, CsrssApiHeap))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
@ -140,6 +189,14 @@ InitWin32Csr()
|
|||
return Status;
|
||||
}
|
||||
Status = CsrRegisterObjectDefinitions(ObjectDefinitions);
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
if (NULL != InitCompleteProc)
|
||||
{
|
||||
Status = AddInitCompleteProc(InitCompleteProc);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -254,7 +311,7 @@ CsrServerInitialization (
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return CallInitComplete();
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# $Id: makefile,v 1.28 2004/04/09 20:03:15 navaraf Exp $
|
||||
# $Id: makefile,v 1.29 2004/05/28 21:33:41 gvg Exp $
|
||||
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
#TARGET_TYPE = program
|
||||
TARGET_TYPE = proglib
|
||||
TARGET_TYPE = program
|
||||
#TARGET_TYPE = proglib
|
||||
|
||||
TARGET_APPTYPE = native
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: dllmain.c,v 1.4 2004/01/19 20:14:28 gvg Exp $
|
||||
/* $Id: dllmain.c,v 1.5 2004/05/28 21:33:41 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -19,6 +19,7 @@
|
|||
|
||||
/* Not defined in any header file */
|
||||
extern VOID STDCALL PrivateCsrssManualGuiCheck(LONG Check);
|
||||
extern VOID STDCALL PrivateCsrssInitialized();
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
|
@ -141,10 +142,18 @@ Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
|
|||
return (CsrExports.CsrReleaseObjectProc)(ProcessData, Object);
|
||||
}
|
||||
|
||||
static BOOL STDCALL
|
||||
Win32CsrInitComplete(void)
|
||||
{
|
||||
PrivateCsrssInitialized();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL STDCALL
|
||||
Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
|
||||
PCSRSS_OBJECT_DEFINITION *ObjectDefinitions,
|
||||
CSRPLUGIN_INIT_COMPLETE_PROC *InitComplete,
|
||||
PCSRSS_EXPORTED_FUNCS Exports,
|
||||
HANDLE CsrssApiHeap)
|
||||
{
|
||||
|
@ -165,6 +174,7 @@ Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
|
|||
|
||||
*ApiDefinitions = Win32CsrApiDefinitions;
|
||||
*ObjectDefinitions = Win32CsrObjectDefinitions;
|
||||
*InitComplete = Win32CsrInitComplete;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: win32csr.edf,v 1.1 2003/12/02 11:38:46 gvg Exp $
|
||||
; $Id: win32csr.edf,v 1.2 2004/05/28 21:33:41 gvg Exp $
|
||||
;
|
||||
;
|
||||
|
||||
|
@ -6,4 +6,4 @@ LIBRARY win32csr.dll
|
|||
|
||||
EXPORTS
|
||||
|
||||
Win32CsrInitialization=Win32CsrInitialization@16
|
||||
Win32CsrInitialization=Win32CsrInitialization@20
|
||||
|
|
18
reactos/subsys/win32k/include/csr.h
Normal file
18
reactos/subsys/win32k/include/csr.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* $Id: csr.h,v 1.1 2004/05/28 21:33:41 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: Interface to csrss
|
||||
* FILE: subsys/win32k/include/csr.h
|
||||
* PROGRAMER: Ge van Geldorp (ge@gse.nl)
|
||||
*/
|
||||
|
||||
#ifndef CSR_H_INCLUDED
|
||||
#define CSR_H_INCLUDED
|
||||
|
||||
extern NTSTATUS FASTCALL CsrInit(void);
|
||||
extern NTSTATUS FASTCALL CsrNotify(PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply);
|
||||
|
||||
#endif /* CSR_H_INCLUDED */
|
||||
|
||||
/* EOF */
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.99 2004/05/13 19:29:47 jfilby Exp $
|
||||
# $Id: makefile,v 1.100 2004/05/28 21:33:40 gvg Exp $
|
||||
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
|
@ -54,12 +54,12 @@ MISC_OBJECTS = misc/driver.o misc/error.o misc/math.o misc/object.o
|
|||
LDR_OBJECTS = ldr/loader.o
|
||||
|
||||
NTUSER_OBJECTS = ntuser/accelerator.o ntuser/callback.o ntuser/caret.o ntuser/class.o \
|
||||
ntuser/clipboard.o ntuser/focus.o ntuser/desktop.o ntuser/guicheck.o \
|
||||
ntuser/hook.o ntuser/hotkey.o ntuser/input.o ntuser/keyboard.o \
|
||||
ntuser/menu.o ntuser/message.o ntuser/metric.o ntuser/misc.o \
|
||||
ntuser/msgqueue.o ntuser/painting.o ntuser/prop.o ntuser/scrollbar.o \
|
||||
ntuser/stubs.o ntuser/timer.o ntuser/useratom.o ntuser/vis.o \
|
||||
ntuser/windc.o ntuser/window.o ntuser/winpos.o ntuser/winsta.o
|
||||
ntuser/clipboard.o ntuser/csr.o ntuser/focus.o ntuser/desktop.o \
|
||||
ntuser/guicheck.o ntuser/hook.o ntuser/hotkey.o ntuser/input.o \
|
||||
ntuser/keyboard.o ntuser/menu.o ntuser/message.o ntuser/metric.o \
|
||||
ntuser/misc.o ntuser/msgqueue.o ntuser/painting.o ntuser/prop.o \
|
||||
ntuser/scrollbar.o ntuser/stubs.o ntuser/timer.o ntuser/useratom.o \
|
||||
ntuser/vis.o ntuser/windc.o ntuser/window.o ntuser/winpos.o ntuser/winsta.o
|
||||
|
||||
OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \
|
||||
objects/color.o objects/coord.o objects/dc.o \
|
||||
|
|
79
reactos/subsys/win32k/ntuser/csr.c
Normal file
79
reactos/subsys/win32k/ntuser/csr.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* $Id: csr.c,v 1.1 2004/05/28 21:33:41 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: Interface to csrss
|
||||
* FILE: subsys/win32k/ntuser/csr.c
|
||||
* PROGRAMER: Ge van Geldorp (ge@gse.nl)
|
||||
*/
|
||||
|
||||
#include <w32k.h>
|
||||
|
||||
static HANDLE WindowsApiPort = NULL;
|
||||
static PEPROCESS CsrProcess = NULL;
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
CsrInit(void)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING PortName;
|
||||
ULONG ConnectInfoLength;
|
||||
|
||||
RtlInitUnicodeString(&PortName, L"\\Windows\\ApiPort");
|
||||
ConnectInfoLength = 0;
|
||||
Status = ZwConnectPort(&WindowsApiPort,
|
||||
&PortName,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&ConnectInfoLength);
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
CsrProcess = PsGetCurrentProcess();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
CsrNotify(PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PEPROCESS OldProcess;
|
||||
|
||||
if (NULL == CsrProcess)
|
||||
{
|
||||
return STATUS_INVALID_PORT_HANDLE;
|
||||
}
|
||||
|
||||
Request->Header.DataSize = sizeof(CSRSS_API_REQUEST) - LPC_MESSAGE_BASE_SIZE;
|
||||
Request->Header.MessageSize = sizeof(CSRSS_API_REQUEST);
|
||||
|
||||
/* Switch to the process in which the WindowsApiPort handle is valid */
|
||||
OldProcess = PsGetCurrentProcess();
|
||||
if (CsrProcess != OldProcess)
|
||||
{
|
||||
KeAttachProcess(CsrProcess);
|
||||
}
|
||||
Status = ZwRequestWaitReplyPort(WindowsApiPort,
|
||||
&Request->Header,
|
||||
&Reply->Header);
|
||||
if (CsrProcess != OldProcess)
|
||||
{
|
||||
KeDetachProcess();
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = Reply->Status;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: desktop.c,v 1.14 2004/05/10 17:07:18 weiden Exp $
|
||||
* $Id: desktop.c,v 1.15 2004/05/28 21:33:41 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -207,47 +207,6 @@ HWND FASTCALL IntGetDesktopWindow(VOID)
|
|||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
|
||||
static NTSTATUS FASTCALL
|
||||
NotifyCsrss(PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING PortName;
|
||||
ULONG ConnectInfoLength;
|
||||
static HANDLE WindowsApiPort = NULL;
|
||||
|
||||
RtlInitUnicodeString(&PortName, L"\\Windows\\ApiPort");
|
||||
ConnectInfoLength = 0;
|
||||
Status = ZwConnectPort(&WindowsApiPort,
|
||||
&PortName,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&ConnectInfoLength);
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
Request->Header.DataSize = sizeof(CSRSS_API_REQUEST) - LPC_MESSAGE_BASE_SIZE;
|
||||
Request->Header.MessageSize = sizeof(CSRSS_API_REQUEST);
|
||||
|
||||
Status = ZwRequestWaitReplyPort(WindowsApiPort,
|
||||
&Request->Header,
|
||||
&Reply->Header);
|
||||
if (! NT_SUCCESS(Status) || ! NT_SUCCESS(Status = Reply->Status))
|
||||
{
|
||||
ZwClose(WindowsApiPort);
|
||||
return Status;
|
||||
}
|
||||
|
||||
// ZwClose(WindowsApiPort);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
IntShowDesktop(PDESKTOP_OBJECT Desktop, ULONG Width, ULONG Height)
|
||||
{
|
||||
|
@ -259,7 +218,7 @@ IntShowDesktop(PDESKTOP_OBJECT Desktop, ULONG Width, ULONG Height)
|
|||
Request.Data.ShowDesktopRequest.Width = Width;
|
||||
Request.Data.ShowDesktopRequest.Height = Height;
|
||||
|
||||
return NotifyCsrss(&Request, &Reply);
|
||||
return CsrNotify(&Request, &Reply);
|
||||
}
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
|
@ -446,7 +405,7 @@ NtUserCreateDesktop(
|
|||
lpszDesktopName->Length);
|
||||
Request.Data.CreateDesktopRequest.DesktopName[lpszDesktopName->Length / sizeof(WCHAR)] = L'\0';
|
||||
|
||||
Status = NotifyCsrss(&Request, &Reply);
|
||||
Status = CsrNotify(&Request, &Reply);
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to notify CSRSS about new desktop\n");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: misc.c,v 1.75 2004/05/21 10:09:31 weiden Exp $
|
||||
/* $Id: misc.c,v 1.76 2004/05/28 21:33:41 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -114,9 +114,13 @@ NtUserCallNoParam(DWORD Routine)
|
|||
case NOPARAM_ROUTINE_ANYPOPUP:
|
||||
Result = (DWORD)IntAnyPopup();
|
||||
break;
|
||||
|
||||
case NOPARAM_ROUTINE_CSRSS_INITIALIZED:
|
||||
Result = (DWORD)CsrInit();
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n");
|
||||
DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine);
|
||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <include/cleanup.h>
|
||||
#include <include/clipboard.h>
|
||||
#include <include/color.h>
|
||||
#include <include/csr.h>
|
||||
#include <include/cursoricon.h>
|
||||
#include <include/dce.h>
|
||||
#include <include/desktop.h>
|
||||
|
|
Loading…
Reference in a new issue