// 下列 ifdef 區塊是建立巨集以協助從 DLL 匯出的標準方式。
// 這個 DLL 中的所有檔案都是使用命令列中所定義 DEVCON_DLL_EXPORTS 符號編譯的。
// 任何使用這個 DLL 的專案都不應定義這個符號。
// 這樣一來，原始程式檔中包含這檔案的任何其他專案
// 會將 DEVCON_DLL_API 函式視為從 DLL 匯入的，而這個 DLL 則會將這些符號視為
// 匯出的。

#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <setupapi.h>
#include <regstr.h>
#include <infstr.h>
#include <cfgmgr32.h>
#include <string.h>
#include <malloc.h>
#include <newdev.h>
#include <objbase.h>
#include <strsafe.h>

#include "msg.h"
#include "rc_ids.h"


#define DEVCON_DLL_API __declspec(dllexport)

/*
#ifdef DEVCON_DLL_EXPORTS
#define DEVCON_DLL_API __declspec(dllexport)
#else
#define DEVCON_DLL_API __declspec(dllimport)
#endif
*/

#ifdef __cplusplus    // If used by C++ code, 
extern "C" {          // we need to export the C interface
#endif



// 這個類別是從 devcon_dll.dll 匯出的
class DEVCON_DLL_API Cdevcon_dll {
public:
	Cdevcon_dll(void);
	// TODO: 在此加入您的方法。
};

extern DEVCON_DLL_API int ndevcon_dll;


const int PCI_PORT_INDEX=4;

#define MAX_SERIAL_PORT_NUMBER			2
#define MAX_SLOT_NUMBER			2

typedef struct _PciMember {
    DWORDLONG address;
	CHAR* PortName;
	int PortNum;
	int index;
} PciMember;

DEVCON_DLL_API int GetPciIoAddress(char* TempString, DWORDLONG* address,const char *ansii_string);
DEVCON_DLL_API int GetPciAdressAndPortMapping(char* TempString, const char *ansii_string, const char *ansii_string2, char* VendorName,char* Path,char* Path2,PciMember* pci1,PciMember* pci2);
//DEVCON_DLL_API int GetPortsName(char* VendorName,char* Path,char** PortsName,int* index, int* count);
DEVCON_DLL_API int GetPortsName(char* VendorName,char* Path,int PortsNum[],int index[], int* count);


#ifdef __cplusplus    // If used by C++ code, 
}
#endif
/*++

Copyright (c) Microsoft Corporation.  All rights reserved.

Module Name:

    devcon.h

Abstract:

    Device Console header

--*/


#ifndef ARRAYSIZE
#define ARRAYSIZE(a)                (sizeof(a)/sizeof(a[0]))
#endif

typedef int (*DispatchFunc)(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in LPTSTR argv[], TCHAR* Template, DWORDLONG* address);
typedef int (*CallbackFunc)(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo, __in DWORD Index, __in LPVOID Context, TCHAR* Template, DWORDLONG* address);


typedef struct {
    LPCTSTR         cmd;
    DispatchFunc    func;
    DWORD           shortHelp;
    DWORD           longHelp;
} DispatchEntry;

extern DispatchEntry DispatchTable[];

#ifndef ARRAYSIZE
#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
#endif

#define INSTANCEID_PREFIX_CHAR TEXT('@') // character used to prefix instance ID's
#define CLASS_PREFIX_CHAR      TEXT('=') // character used to prefix class name
#define WILD_CHAR              TEXT('*') // wild character
#define QUOTE_PREFIX_CHAR      TEXT('\'') // prefix character to ignore wild characters
#define SPLIT_COMMAND_SEP      TEXT(":=") // whole word, indicates end of id's

//
// Devcon.exe command line flags
//
#define DEVCON_FLAG_FORCE       0x00000001


bool GetPciAvaliable(char* VendorName,char* Path);
int GetParentIdPrefixRegistryValue(char* VendorName,char* Path,WCHAR* ParentIdPrefixName);
int GetPortnameRegistryValue(WCHAR* ParentIdPrefixName, int* count, WCHAR** Portname);
int GetPciAdressAndPortMapping(char* TempString, const char *ansii_string, const char *ansii_string2, char* VendorName,char* Path,char* Path2,PciMember* pci1,PciMember* pci2);

//int GetPciIoAddress(char* TempString, DWORDLONG* address,const char *ansii_string,__in int argc, __in PZPWSTR argv);
void FormatToStream(__in FILE * stream, __in DWORD fmt,...);
void Padding(__in int pad);
bool SplitCommandLine(__inout int & argc, __inout LPTSTR * & argv, __out int & argc_right,  __out LPTSTR * & argv_right);
int EnumerateDevices(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in PZPWSTR argv, __in CallbackFunc Callback, __in LPVOID Context, TCHAR* Template, DWORDLONG* address);
LPTSTR GetDeviceStringProperty(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo, __in DWORD Prop);
LPTSTR GetDeviceDescription(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo);
__drv_allocatesMem(object) LPTSTR * GetDevMultiSz(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo, __in DWORD Prop);
__drv_allocatesMem(object) LPTSTR * GetRegMultiSz(__in HKEY hKey, __in LPCTSTR Val);
__drv_allocatesMem(object) LPTSTR * GetMultiSzIndexArray(__in __drv_aliasesMem LPTSTR MultiSz);
void DelMultiSz(__in_opt __drv_freesMem(object) PZPWSTR Array);
__drv_allocatesMem(object) LPTSTR * CopyMultiSz(__in_opt PZPWSTR Array);

BOOL DumpArray(__in int pad, __in PZPWSTR Array);
BOOL DumpDevice(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo);
BOOL DumpDeviceClass(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo);
LPTSTR DumpDeviceDescr(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo);
BOOL DumpDeviceStatus(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo);
PBYTE DumpDeviceResources(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo);
BOOL DumpDeviceDriverFiles(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo);
BOOL DumpDeviceDriverNodes(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo);
BOOL DumpDeviceHwIds(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo);
TCHAR* DumpDeviceWithInfo(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo, __in_opt LPCTSTR Info);
BOOL DumpDeviceStack(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo);
BOOL DumpDriverPackageData(__in LPCTSTR InfName);
BOOL Reboot();


//
// UpdateDriverForPlugAndPlayDevices
//
typedef BOOL (WINAPI *UpdateDriverForPlugAndPlayDevicesProto)(__in HWND hwndParent,
                                                              __in LPCTSTR HardwareId,
                                                              __in LPCTSTR FullInfPath,
                                                              __in DWORD InstallFlags,
                                                              __out_opt PBOOL bRebootRequired
                                                         );
typedef BOOL (WINAPI *SetupSetNonInteractiveModeProto)(__in BOOL NonInteractiveFlag
                                                      );
typedef BOOL (WINAPI *SetupUninstallOEMInfProto)(__in LPCTSTR InfFileName,
                                                 __in DWORD Flags,
                                                 __reserved PVOID Reserved
                                                 );

#if _SETUPAPI_VER >= _WIN32_WINNT_WINXP
typedef BOOL (WINAPI *SetupVerifyInfFileProto)(__in LPCTSTR InfName,
                                               __in_opt PSP_ALTPLATFORM_INFO_V2 AltPlatformInfo,
                                               __inout PSP_INF_SIGNER_INFO InfSignerInfo );
#endif

#ifdef _UNICODE
#define UPDATEDRIVERFORPLUGANDPLAYDEVICES "UpdateDriverForPlugAndPlayDevicesW"
#define SETUPUNINSTALLOEMINF "SetupUninstallOEMInfW"
#else
#define UPDATEDRIVERFORPLUGANDPLAYDEVICES "UpdateDriverForPlugAndPlayDevicesA"
#define SETUPUNINSTALLOEMINF "SetupUninstallOEMInfA"
#endif
#define SETUPSETNONINTERACTIVEMODE "SetupSetNonInteractiveMode"
#define SETUPVERIFYINFFILE "SetupVerifyInfFile"

//
// exit codes
//
#define EXIT_OK      (0)
#define EXIT_REBOOT  (1)
#define EXIT_FAIL    (2)
#define EXIT_USAGE   (3)





