⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packet32.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:

/** @ingroup packetapi
 *  @{
 */

/** @defgroup packet32 Packet.dll exported functions and variables
 *  @{
 */

/// Current packet.dll Version. It can be retrieved directly or through the PacketGetVersion() function.
char PacketLibraryVersion[] = "2.3"; 

/*! 
  \brief Returns a string with the dll version.
  \return A char pointer to the version of the library.
*/
PCHAR PacketGetVersion(){
	return PacketLibraryVersion;
}

/*! 
  \brief Returns information about the MAC type of an adapter.
  \param AdapterObject The adapter on which information is needed.
  \param type Pointer to a NetType structure that will be filled by the function.
  \return If the function succeeds, the return value is nonzero, otherwise the return value is zero.

  This function return the link layer technology and the speed (in bps) of an opened adapter.
  The LinkType field of the type parameter can have one of the following values:

  - NdisMedium802_3: Ethernet (802.3) 
  - NdisMediumWan: WAN 
  - NdisMedium802_5: Token Ring (802.5) 
  - NdisMediumFddi: FDDI 
  - NdisMediumAtm: ATM 
  - NdisMediumArcnet878_2: ARCNET (878.2) 
*/
BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type)
{
    BOOLEAN    Status;
    ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
    PPACKET_OID_DATA  OidData;

    OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
    if (OidData == NULL) {
        ODS("PacketGetNetType failed\n");
        return FALSE;
    }
	//get the link-layer type
    OidData->Oid = OID_GEN_MEDIA_IN_USE;
    OidData->Length = sizeof (ULONG);
    Status = PacketRequest(AdapterObject,FALSE,OidData);
    type->LinkType=*((UINT*)OidData->Data);

	//get the link-layer speed
    OidData->Oid = OID_GEN_LINK_SPEED;
    OidData->Length = sizeof (ULONG);
    Status = PacketRequest(AdapterObject,FALSE,OidData);
	type->LinkSpeed=*((UINT*)OidData->Data)*100;
    GlobalFreePtr (OidData);

	ODSEx("Media:%d ",type->LinkType);
	ODSEx("Speed=%d\n",type->LinkSpeed);

    return Status;
}

/*! 
  \brief Stops and unloads the WinPcap device driver.
  \return If the function succeeds, the return value is nonzero, otherwise it is zero.

  This function can be used to unload the driver from memory when the application no more needs it.
  Note that the driver is physically stopped and unloaded only when all the files on its devices 
  are closed, i.e. when all the applications that use WinPcap close all their adapters.
*/
BOOL PacketStopDriver()
{
	SC_HANDLE		scmHandle;
    SC_HANDLE       schService;
    BOOL            ret;
    SERVICE_STATUS  serviceStatus;

	scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	
	if(scmHandle != NULL){
		
		schService = OpenService (scmHandle,
			NPFServiceName,
			SERVICE_ALL_ACCESS
			);
		
		if (schService != NULL)
		{
			
			ret = ControlService (schService,
				SERVICE_CONTROL_STOP,
				&serviceStatus
				);
			if (!ret)
			{
			}
			
			CloseServiceHandle (schService);
			
			CloseServiceHandle(scmHandle);
			
			return ret;
		}
	}
	
	return FALSE;

}

/*! 
  \brief Opens an adapter.
  \param AdapterName A string containing the name of the device to open. 
   Use the PacketGetAdapterNames() function to retrieve the list of available devices.
  \return If the function succeeds, the return value is the pointer to a properly initialized ADAPTER object,
   otherwise the return value is NULL.

  This function tries to load and start the packet driver at the first invocation. In this way, 
  the management of the driver is transparent to the application, that simply needs to open an adapter to start
  WinPcap.
  
  \note the Windows 95 version of the NPF driver works with the ASCII string format, while the Windows NT 
  version works with UNICODE. Therefore, AdapterName \b should be an ASCII string in Windows 95, and a UNICODE 
  string in Windows NT. This difference is not a problem if the string pointed by AdapterName was obtained 
  through the PacketGetAdapterNames function, because it returns the names of the adapters in the proper format.
  Problems can arise in Windows NT when the string is obtained from ANSI C functions like scanf, because they 
  use the ASCII format. Since this could be a relevant problem during the porting of command-line applications 
  from UNIX, we included in the Windows NT version of PacketOpenAdapter the ability to detect ASCII strings and
  convert them to UNICODE before sending them to the device driver. Therefore PacketOpenAdapter in Windows NT 
  accepts both the ASCII and the UNICODE format. If a ASCII string is received, it is converted to UNICODE 
  by PACKET.DLL before being passed to the driver.
*/
LPADAPTER PacketOpenAdapter(LPTSTR AdapterName)
{
    LPADAPTER lpAdapter;
    BOOLEAN Result;
	char *AdapterNameA;
	WCHAR *AdapterNameU;
	DWORD error;
	SC_HANDLE svcHandle = NULL;
	TCHAR driverPath[512];
	TCHAR WinPath[256];
	LONG KeyRes;
	HKEY PathKey;
	SERVICE_STATUS SStat;
	BOOLEAN QuerySStat;
	WCHAR SymbolicLink[128];

    ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName);

	scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if(scmHandle == NULL){
		error = GetLastError();
		ODSEx("OpenSCManager failed! Error=%d\n", error);
	} else {
		*driverPath = 0;
		GetCurrentDirectory(512, driverPath);
		wsprintf(driverPath + wcslen(driverPath), NPFDriverName);
		
		// check if the NPF registry key is already present
		// this means that the driver is already installed and that we don't need to call PacketInstallDriver
		KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
			NPFRegistryLocation,
			0,
			KEY_READ,
			&PathKey);
		
		if(KeyRes != ERROR_SUCCESS){
			Result = PacketInstallDriver(scmHandle,&svcHandle,driverPath);
		} else {
			Result = TRUE;
			RegCloseKey(PathKey);
		}
		
		if (Result) {
			
			srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
			if (srvHandle != NULL){
				
				QuerySStat = QueryServiceStatus(srvHandle, &SStat);
				ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
				
				if (!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
					ODS("Calling startservice\n");
					if (StartService(srvHandle, 0, NULL)==0){ 
						error = GetLastError();
						if (error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
							SetLastError(error);
							if (scmHandle != NULL) CloseServiceHandle(scmHandle);
							error = GetLastError();
							ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
							return NULL;
						}
					}				
				}
			} else {
				error = GetLastError();
				ODSEx("OpenService failed! Error=%d", error);
			}
		} else {
			if (GetSystemDirectory(WinPath, sizeof(WinPath)/sizeof(TCHAR)) == 0) {
				return FALSE;
			}
			wsprintf(driverPath, TEXT("%s\\drivers%s"), WinPath, NPFDriverName);
			
			if (KeyRes != ERROR_SUCCESS) {
				Result = PacketInstallDriver(scmHandle,&svcHandle,driverPath);
			} else {
				Result = TRUE;
			}
			if (Result) {
				srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
				if (srvHandle != NULL) {
					QuerySStat = QueryServiceStatus(srvHandle, &SStat);
					ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
					if (!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING) {
						ODS("Calling startservice\n");
						if (StartService(srvHandle, 0, NULL) == 0) { 
							error = GetLastError();
							if (error != ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS) {
								SetLastError(error);
								if (scmHandle != NULL) CloseServiceHandle(scmHandle);
								ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
								return NULL;
							}
						}
					}
				} else {
					error = GetLastError();
					ODSEx("OpenService failed! Error=%d", error);
				}
			}
		}
	}
    if (scmHandle != NULL) CloseServiceHandle(scmHandle);

	AdapterNameA = (char*)AdapterName;
	if (AdapterNameA[1] != 0) {  // ASCII
		AdapterNameU = SChar2WChar(AdapterNameA);
		AdapterName = AdapterNameU;
	} else {			         // Unicode
		AdapterNameU = NULL;
	}
	
	lpAdapter = (LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(ADAPTER));
	if (lpAdapter == NULL) {
		ODS("PacketOpenAdapter: GlobalAlloc Failed\n");
		error = GetLastError();
		if (AdapterNameU != NULL) free(AdapterNameU);
		//set the error to the one on which we failed
		SetLastError(error);
	    ODS("PacketOpenAdapter: Failed to allocate the adapter structure\n");
		return NULL;
	}
	lpAdapter->NumWrites = 1;

	wsprintf(SymbolicLink,TEXT("\\\\.\\%s%s"), DOSNAMEPREFIX, &AdapterName[8]);
	
	// Copy  only the bytes that fit in the adapter structure.
	// Note that lpAdapter->SymbolicLink is present for backward compatibility but will
	// never be used by the apps
	memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH);

	//try if it is possible to open the adapter immediately
	lpAdapter->hFile = CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,0,0);
	
	if (lpAdapter->hFile != INVALID_HANDLE_VALUE) {
	    ODSEx("PacketOpenAdapter: CreateFile(%S) successfull\n", SymbolicLink);
		if (PacketSetReadEvt(lpAdapter) == FALSE) {
			error = GetLastError();
			ODS("PacketOpenAdapter: Unable to open the read event\n");
			if (AdapterNameU != NULL)
				free(AdapterNameU);
			GlobalFreePtr(lpAdapter);
			//set the error to the one on which we failed
			SetLastError(error);
		    ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=%d\n",error);
			return NULL;
		}		
		
		PacketSetMaxLookaheadsize(lpAdapter);
		if (AdapterNameU != NULL)
		    free(AdapterNameU);
		return lpAdapter;
	}
	//this is probably the first request on the packet driver. 
	//We must create the dos device and set the access rights on it
	else {
		Result = DefineDosDevice(DDD_RAW_TARGET_PATH,
                                 &SymbolicLink[4],
                                 AdapterName);
		if (Result) {

		    ODSEx("PacketOpenAdapter: calling CreateFile(%S)\n", SymbolicLink);
			
			lpAdapter->hFile = CreateFile(
                                 SymbolicLink,
                                 GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,0,0);
			if (lpAdapter->hFile != INVALID_HANDLE_VALUE) {		
				if (PacketSetReadEvt(lpAdapter) == FALSE) {
					error = GetLastError();
					ODS("PacketOpenAdapter: Unable to open the read event\n");
					if (AdapterNameU != NULL)
						free(AdapterNameU);
					GlobalFreePtr(lpAdapter);
					//set the error to the one on which we failed
					SetLastError(error);
				    ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=1,%d\n",error);
					return NULL;					
				}
				PacketSetMaxLookaheadsize(lpAdapter);
				if (AdapterNameU != NULL)
				    free(AdapterNameU);
				return lpAdapter;
			} else {
        	    ODS("PacketOpenAdapter: CreateFile failed\n");
			}
		} else {
    	    ODSEx("PacketOpenAdapter: DefineDosDevice(%S) failed\n", &SymbolicLink[4]);
		}
	}
	error = GetLastError();
	if (AdapterNameU != NULL)
	    free(AdapterNameU);
	GlobalFreePtr(lpAdapter);
	//set the error to the one on which we failed
	SetLastError(error);
    ODSEx("PacketOpenAdapter: CreateFile failed, Error=2,%d\n",error);
	return NULL;

}

/*! 
  \brief Closes an adapter.
  \param lpAdapter the pointer to the adapter to close. 

  PacketCloseAdapter closes the given adapter and frees the associated ADAPTER structure
*/
VOID PacketCloseAdapter(LPADAPTER lpAdapter)
{
    CloseHandle(lpAdapter->hFile);
	SetEvent(lpAdapter->ReadEvent);
    CloseHandle(lpAdapter->ReadEvent);
    GlobalFreePtr(lpAdapter);
}

/*! 
  \brief Allocates a _PACKET structure.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -