📄 listensd.cpp
字号:
// ListenSD.cpp : 定义 DLL 应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
#include "cryptinfo.h"
#include <Msgqueue.h>
#include <pnp.h>
#define EXIT_ON_NULL(_p) \
if (_p == NULL) \
{ \
hr = E_OUTOFMEMORY; \
goto FuncExit; \
}
#define EXIT_ON_FALSE(_f) \
if (!(_f)) \
{ \
hr = E_FAIL; \
goto FuncExit; \
}
#define TAPI_API_LOW_VERSION 0x00020000
#define TAPI_API_HIGH_VERSION 0x00020000
#define EXT_API_HIGH_VERSION 0x00010000
#define EXT_API_LOW_VERSION 0x00010000
#define CAPS_BUFFER_SIZE 512
#define GUID1 {0xA4E7EDDA,0xE575,0x4252,0x9D,0x6B,0x41,0x95,0xD4,0x8B,0xB8,0x65};
typedef struct
{
TCHAR szPhoneNumber[15+1]; // cell phone number
TCHAR szIMEI[20+1];
TCHAR szIMSI[15+1];
}ClientInfo,*PClientInfo;
typedef union {
DEVDETAIL d;
char pad[sizeof(DEVDETAIL)+MAX_DEVCLASS_NAMELEN];
} MYDEV;
HMODULE hCert = LoadLibrary(TEXT("crypt32.dll"));
CertHandle ch;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
/*
Get the first file under cert directory,return the handle of the file
@szPath, file path of the directory
@szFileName, out paramter, the file's name that got
*/
HANDLE GetFirstChild(const WCHAR *szPath,WCHAR* szFileName)
{
WIN32_FIND_DATA wfd;
HANDLE hFile;
WCHAR* path = new WCHAR[40];
wsprintf(path,TEXT("%s/*"),szPath);
hFile = FindFirstFile(path,&wfd);
if(hFile != INVALID_HANDLE_VALUE) //if file is valid assign the name to szFileName
{
wsprintf(szFileName,TEXT("%s"),wfd.cFileName);
return hFile;
}
else
{
return INVALID_HANDLE_VALUE;
}
}
/*
Enumerate files under the cert directory
@hFile
the first file got
@lpBuffer
file name got
@len
reserved.
*/
BOOL EnumFile(HANDLE hFile, WCHAR *lpBuffer, DWORD* len)
{
WIN32_FIND_DATA wfd;
if(hFile != INVALID_HANDLE_VALUE && FindNextFile(hFile,&wfd))
{
wsprintf(lpBuffer,TEXT("%s"),wfd.cFileName);
return 1;
}
else
{
FindClose(hFile);
return 0;
}
}
/*
Get the file handle specified by @path
@path
file path
*/
HANDLE GetFile(const WCHAR* path)
{
HANDLE hFile = CreateFile(path,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("Invalid file path.\n");
}
return hFile;
}
/*
Get file size
@hFile
file handle to get file size
@sizeHigh
file size high part 4 bytes
@sizeLow
file size low part 4 bytes
*/
BOOL GetSize(HANDLE hFile, LPDWORD sizeHigh, LPDWORD sizeLow)
{
BOOL noError = true;
if(sizeHigh == NULL) // means size is stored in @sizeLow
{
*sizeLow = GetFileSize(hFile,NULL);
if(*sizeLow == 0xFFFFFFFF) //Get file size error
{
noError = 0;
}
}
else
{
*sizeLow = GetFileSize(hFile,sizeHigh);
if(*sizeLow == 0xFFFFFFFF && GetLastError() != NO_ERROR) //means error occured
{
noError = 0;
}
}
return noError;
}
/*
Read data from file
@file
the file handle that read data from
@lpBuffer
the data buffer
@requestSize
the size expected to read
@actualSize
the size actually read
return TRUE or FALSE
*/
BOOL ReadData(HANDLE file, BYTE *lpBuffer, DWORD requestSize, DWORD *actualSize)
{
if(INVALID_HANDLE_VALUE == file)
{
printf("No file to read.");
return 0;
}
BOOL ret = ReadFile(file,(LPVOID)lpBuffer,requestSize,actualSize,NULL);
if(ret==0)
{
printf("Read file failure.");
*actualSize = 0;
}
CloseHandle(file);
return ret;
}
/*
Init all certificate about <code>CAPI</code> APIs.
*/
void initFuncs()
{
ch.context = (CERTCREATECERTIFICATECONTEXT)GetProcAddress(hCert,TEXT("CertCreateCertificateContext"));
ch.freeContext = (CERTFREECERTIFICATECONTEXT)GetProcAddress(hCert,TEXT("CertFreeCertificateContext"));
ch.getName = (GETNAMESTRING)GetProcAddress(hCert,TEXT("CertGetNameStringW"));
ch.getct = (GETCERTSTORE)GetProcAddress(hCert,TEXT("CertOpenStore"));
ch.enumcert = (ENUMCERT)GetProcAddress(hCert,TEXT("CertEnumCertificatesInStore"));
ch.certName = (CERTNAMESTR)GetProcAddress(hCert,TEXT("CertNameToStrW"));
ch.getPubKeyInfo = (PUBLICKEYINFO)GetProcAddress(hCert,TEXT("CryptImportPublicKeyInfoEx"));
ch.comparePubKeyInfo = (COMPAREPUBLICKEYINFO)GetProcAddress(hCert,TEXT("CertComparePublicKeyInfo"));
ch.compareCert = (COMPARECERT)GetProcAddress(hCert,TEXT("CertCompareCertificate"));
ch.deleteFromStore = (DELETEFORMSTRORE)GetProcAddress(hCert,TEXT("CertDeleteCertificateFromStore"));
ch.closeStore = (CLOSESTORE)GetProcAddress(hCert,TEXT("CertCloseStore"));
ch.enumCertInStore = (ENUMCERTINSTORE)GetProcAddress(hCert,TEXT("CertEnumCertificatesInStore"));
ch.duplicateContext = (DUPLICATECONTEXT)GetProcAddress(hCert,TEXT("CertDuplicateCertificateContext"));
ch.enumSysStores = (ENUMSYSTEMSTORES)GetProcAddress(hCert,TEXT("CertEnumSystemStore"));
ch.enumSystemStoreLoc = (ENUMSYSTEMSTORELOC)GetProcAddress(hCert,TEXT("CertEnumSystemStoreLocation"));
ch.enumPhsicalStore = (ENUMPHISICALSTORE)GetProcAddress(hCert,TEXT("CertEnumPhysicalStore"));
ch.addCertToStore = (ADDCERTTOSTORE)GetProcAddress(hCert,TEXT("CertAddCertificateContextToStore"));
}
/*
Get the ASN.1 encoded certificate context
@fileName
the name of file that to get the certificate
*/
PCCERT_CONTEXT getCertContext(const WCHAR* fileName)
{
WCHAR* path = new WCHAR[40];
DWORD actual;
wsprintf(path,TEXT("/存储卡/CSP/%s"),fileName);
HANDLE f = GetFile(path);
DWORD offSize,low;
GetSize(f,&offSize,&low);
BYTE* contents = new BYTE[low+1];
ReadData(f,contents,low,&actual);
return ch.context(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,contents,actual);
}
/*
Export the certificate context to system cert store
@pContext
the certificate context to export
*/
void ExportCert(PCCERT_CONTEXT pContext)
{
//System store name to export certs to
WCHAR* pszStoreName = new WCHAR[10];
wsprintf(pszStoreName,TEXT("%s"),TEXT("My"));
PCCERT_CONTEXT contextCpy;
//Get system cert store handle
HANDLE hStoreHandle;
hStoreHandle = ch.getct( CERT_STORE_PROV_SYSTEM_W, 0,NULL,CERT_STORE_NO_CRYPT_RELEASE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,pszStoreName);
//Add cert to store
if(!ch.addCertToStore(hStoreHandle,pContext,CERT_STORE_ADD_ALWAYS,&contextCpy))
MessageBox(NULL,TEXT("Tip"),TEXT("Add Failed."),MB_OK);
//Release the created copy context
ch.freeContext(contextCpy);
//Close store
ch.closeStore(hStoreHandle,0);
}
/*
Retract certificate from system store
@targetContext
the certificate context to retract from system store
*/
void RetractCert(PCCERT_CONTEXT targetContext)
{
HANDLE hStoreHandle;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pDupCertContext;
PCERT_PUBLIC_KEY_INFO pOldPubKey = NULL;
PCERT_PUBLIC_KEY_INFO pNewPubKey;
WCHAR* pszStoreName = new WCHAR[10];
WCHAR* pszNameString = new WCHAR[50];
pOldPubKey = &(targetContext->pCertInfo->SubjectPublicKeyInfo);
wsprintf(pszStoreName,TEXT("%s"),TEXT("My"));
hStoreHandle = ch.getct( CERT_STORE_PROV_SYSTEM_W, 0,NULL,CERT_STORE_NO_CRYPT_RELEASE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,pszStoreName);
//Enumerate the certificate context that in system store "My"
while(pCertContext= ch.enumCertInStore(hStoreHandle,pCertContext))
{
ch.getName( pCertContext,CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,NULL, (LPWSTR)pszNameString,128);
pNewPubKey = &(pCertContext->pCertInfo->SubjectPublicKeyInfo);
if(pOldPubKey) //Check whether public key info is got
if(ch.comparePubKeyInfo(MY_ENCODING_TYPE,pOldPubKey,pNewPubKey)) //compare two public keys' info
{
printf("The public keys are the same.\n");
}
else
{
printf("This certificate has a different public key.\n");
continue;
}
if(pDupCertContext = ch.duplicateContext(pCertContext)) //duplicate the certificate context in store
{
printf("A duplicate pointer was created. Continue. \n");
}
//Compare two certificate context
if(ch.compareCert(
X509_ASN_ENCODING,
targetContext->pCertInfo,
pCertContext->pCertInfo))
{
printf("The two certificates are identical. \n");
}
else
{
printf("The two certificates are not identical. \n");
continue;
}
//Delete certificate context from system store
if(ch.deleteFromStore(pDupCertContext))
{
printf("Delete successfully!");
break;
}
else
{
printf("The deletion of the certificate failed.\n");
}
}
ch.closeStore(hStoreHandle,0);
}
void ListenSD()
{
MSGQUEUEOPTIONS MqOpts;
MqOpts.dwSize = sizeof(MSGQUEUEOPTIONS);
MqOpts.bReadAccess = TRUE;
MqOpts.cbMaxMessage = sizeof(DEVDETAIL) + MAX_PATH*sizeof(wchar_t);
MqOpts.dwFlags = MSGQUEUE_NOPRECOMMIT;
MqOpts.dwMaxMessages = 0;
HANDLE hMsgQ = CreateMsgQueue(NULL, &MqOpts);
HANDLE waitable;
//if message queue created begin to register notifications
if (hMsgQ != NULL)
{
GUID guid = GUID1;
waitable = RequestDeviceNotifications(&guid, hMsgQ, FALSE);
}
else
{
return;
}
MYDEV detail;
DWORD flags;
DWORD size;
WCHAR* szFile = new WCHAR[20];
PCCERT_CONTEXT pCert;
PCCERT_CONTEXT certs[4];
int eCount = 0;
//Read message from message queue without stop
while (ReadMsgQueue(hMsgQ, &detail, sizeof(detail), &size, INFINITE, &flags) == TRUE)
{
//Device inserted
if(detail.d.fAttached)
{
for(int i =0; i < 4;i++)
certs[i] = NULL;
WIN32_FIND_DATA wfd;
HANDLE hFile;
WCHAR* path = TEXT("/存储卡/CSP");
hFile = FindFirstFile(path,&wfd);
DWORD ti = 1000;
//Try to get the directory to check whether card is ready
while(hFile == INVALID_HANDLE_VALUE && ti < 3001)
{
Sleep(ti);
hFile = FindFirstFile(path,&wfd);
ti = ti + 1000;
}
HANDLE file = GetFirstChild(TEXT("/存储卡/CSP"),szFile);
//If get the certificate context just export it
if((pCert = getCertContext(szFile))!=NULL)
{
ExportCert(pCert);
certs[eCount ++] = pCert;
}
DWORD len = 20;
//Read other certs
while(EnumFile(file,szFile,&len))
{
if((pCert = getCertContext(szFile))!=NULL)
{
certs[eCount ++] = pCert;
ExportCert(pCert);
}
}
}
else
{
//Retract certificate context from system cert store
while(eCount > 0)
{
RetractCert(certs[--eCount]);
}
}
}
StopDeviceNotifications(waitable);
CloseMsgQueue(hMsgQ);
}
unsigned long __cdecl MyControllingFunction( LPVOID pParam )
{
ListenSD();
return 0;
}
DWORD MSL_Close(DWORD dwData)
{
return 0;
}
DWORD MSL_Deinit(DWORD dwData)
{
return 0;
}
DWORD MSL_Init(DWORD dwData)
{
initFuncs();
HANDLE hThread = CreateThread( 0, 0, MyControllingFunction, 0, 0, 0);
return 1;
}
DWORD MSL_IOControl(
DWORD dwData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
return 1;
}
DWORD MSL_Open(
DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode)
{
return 0;
}
DWORD MSL_Read(
DWORD dwData,
LPVOID pBuf,
DWORD dwLen)
{
return 0;
}
DWORD MSL_Seek(
DWORD dwData,
long pos,
DWORD type)
{
return 0;
}
DWORD MSL_Write(
DWORD dwData,
LPCVOID pInBuf,
DWORD dwInLen)
{
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -