www.pudn.com > tdi_fw.zip > tdi_install.c


// $Id: tdi_install.c,v 1.5 2002/12/05 13:03:05 dev Exp $ 
 
#include  
#include  
 
static void		install_driver(void); 
static void		uninstall_driver(void); 
 
int 
main(int argc, char **argv) 
{ 
	if (argc != 2) { 
		fprintf(stderr, "use: %s install|remove\n", argv[0]); 
		return 0; 
	} 
 
	if (strcmp(argv[1], "install") == 0) 
		install_driver(); 
	else if (strcmp(argv[1], "remove") == 0) 
		uninstall_driver(); 
	else 
		fprintf(stderr, "Invalid command line! \"%s\" is not \"install\" or \"remove\"\n", argv[1]); 
 
	return 0; 
} 
 
#define DRIVER_NAME		"tdi_fw" 
#define DRIVER_BINARY	"system32\\drivers\\tdi_fw.sys" 
#define DRIVER_GROUP	"PNP_TDI" 
#define DRIVER_DEPENDS	"tcpip\0\0" 
 
#define swap_dword(a, b)	\ 
	do {					\ 
		DWORD c =(a);		\ 
		(a) = (b);			\ 
		(b) = c;			\ 
	} while(0) 
 
void 
install_driver(void) 
{ 
	SC_HANDLE sch, tdi_fw, tcpip, netbt; 
	DWORD tdi_fw_tag, tcpip_tag, netbt_tag, n, tags[100], type, i; 
	char buf[2048]; 
	QUERY_SERVICE_CONFIG *cfg = (QUERY_SERVICE_CONFIG *)buf; 
	HKEY reg_key; 
	LONG status; 
	int n_type; 
	BOOL has_tcpip, has_netbt, has_tdi_fw; 
 
	// install driver like instdrv does 
 
    sch = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 
	if (sch == NULL) { 
		fprintf(stderr, "OpenSCManager: %d\n", GetLastError()); 
		return; 
	} 
 
    tdi_fw = CreateService(sch, 
                            DRIVER_NAME, 
                            DRIVER_NAME, 
                            SERVICE_ALL_ACCESS, 
                            SERVICE_KERNEL_DRIVER, 
                            SERVICE_SYSTEM_START, 
                            SERVICE_ERROR_NORMAL, 
                            DRIVER_BINARY, 
                            DRIVER_GROUP, 
                            &tdi_fw_tag, 
                            DRIVER_DEPENDS, 
                            NULL, 
                            NULL 
                            ); 
	if (tdi_fw == NULL) { 
		fprintf(stderr, "CreateService: %d\n", GetLastError()); 
		return; 
	} 
 
	// get tag for tcpip 
 
	tcpip = OpenService(sch, "tcpip", SERVICE_ALL_ACCESS); 
	if (tcpip == NULL) { 
		fprintf(stderr, "OpenService(tcpip): %d\n", GetLastError()); 
		return; 
	} 
 
	if (!QueryServiceConfig(tcpip, cfg, sizeof(buf), &n)) { 
		fprintf(stderr, "QueryServiceConfig(tcpip): %d\n", GetLastError()); 
		return; 
	} 
	tcpip_tag = cfg->dwTagId; 
 
	// get tag for netbt 
 
	netbt = OpenService(sch, "netbt", SERVICE_ALL_ACCESS); 
	if (netbt == NULL) { 
		fprintf(stderr, "OpenService(netbt): %d\n", GetLastError()); 
		return; 
	} 
 
	if (!QueryServiceConfig(netbt, cfg, sizeof(buf), &n)) { 
		fprintf(stderr, "QueryServiceConfig(tcpip): %d\n", GetLastError()); 
		return; 
	} 
	netbt_tag = cfg->dwTagId; 
 
	// change tags for all drivers 
 
	// 1. tcpip 
	// 2. tdi_fw 
	// 3. netbt 
 
	// get registry key 
 
	status = RegOpenKey(HKEY_LOCAL_MACHINE, 
		"SYSTEM\\CurrentControlSet\\Control\\GroupOrderList", ®_key); 
	if (status != ERROR_SUCCESS) { 
		fprintf(stderr, "RegOpenKey: %d\n", status); 
		return; 
	} 
 
	n = sizeof(tags) - sizeof(DWORD) * 3;		// reserve space for 3 new items 
	status = RegQueryValueEx(reg_key, DRIVER_GROUP, NULL, &type, (LPBYTE)tags, &n); 
	if (status != ERROR_SUCCESS) { 
		fprintf(stderr, "RegQueryValueEx: %d\n", status); 
		return; 
	} 
 
	// find each num 
 
	n /= sizeof(DWORD); 
 
	// try to find tag for tdi_fw if not found add it 
	has_tdi_fw = FALSE; 
	for (i = 1; i < n; i++) 
		if (tags[i] == tdi_fw_tag) { 
			has_tdi_fw = TRUE; 
			break; 
		} 
 
	if (!has_tdi_fw) 
		tags[n++] = tdi_fw_tag; 
 
	has_tcpip = has_netbt = FALSE; 
	n_type = 1; 
 
	for (i = 1; i < n; i++) 
		if (tags[i] == tcpip_tag || tags[i] == netbt_tag || tags[i] == tdi_fw_tag) { 
 
			switch (n_type) { 
			case 1: 
				// 1. tcpip 
				tags[i] = tcpip_tag; 
				has_tcpip = TRUE; 
				break; 
			case 2: 
				// 2. tdi_fw 
				tags[i] = tdi_fw_tag; 
				break; 
			case 3: 
				// 3. netbt_tag 
				tags[i] = netbt_tag; 
				has_netbt = TRUE; 
				break; 
			} 
			n_type++; 
 
		} 
 
	if (!has_tcpip) { 
		printf("Warning! tcpip with tag %d not found! Trying to restore registry GroupOrderList key...\n", tcpip_tag); 
		 
		// insert at the begin of list 
		memmove(&tags[1], &tags[2], (n - 1) * sizeof(DWORD)); 
		tags[1] = tcpip_tag; 
		n++; 
	} 
	if (!has_netbt) { 
		printf("Warning! netbt with tag %d not found! Trying to restore registry GroupOrderList key...\n", netbt_tag); 
 
		// append to the end of list 
		tags[n++] = netbt_tag; 
	} 
 
	// save number of entries 
	tags[0] = n - 1; 
 
	// that's all. save new order 
 
	status = RegSetValueEx(reg_key, DRIVER_GROUP, 0, type, (LPBYTE)tags, n * sizeof(DWORD)); 
	if (status != ERROR_SUCCESS) { 
		fprintf(stderr, "RegSetValueEx: %d\n", status); 
		return; 
	} 
 
	// ok 
	RegCloseKey(reg_key); 
	CloseServiceHandle(tcpip); 
	CloseServiceHandle(tdi_fw); 
	CloseServiceHandle(netbt); 
	CloseServiceHandle(sch); 
 
	printf("success\n"); 
} 
 
void 
uninstall_driver(void) 
{ 
	SC_HANDLE sch, service; 
	DWORD tags[100], n, type, i, service_tag; 
	char buf[2048]; 
	HKEY reg_key; 
	QUERY_SERVICE_CONFIG *cfg = (QUERY_SERVICE_CONFIG *)buf; 
	int status; 
 
    sch = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 
	if (sch == NULL) { 
		fprintf(stderr, "OpenSCManager: %d\n", GetLastError()); 
		return; 
	} 
 
	// get tag for driver 
 
	service = OpenService(sch, DRIVER_NAME, SERVICE_ALL_ACCESS); 
	if (service == NULL) { 
		fprintf(stderr, "OpenService: %d\n", GetLastError()); 
		return; 
	} 
 
	if (!QueryServiceConfig(service, cfg, sizeof(buf), &n)) { 
		fprintf(stderr, "QueryServiceConfig(tcpip): %d\n", GetLastError()); 
		return; 
	} 
	service_tag = cfg->dwTagId; 
 
	// remove tag from registry 
 
	status = RegOpenKey(HKEY_LOCAL_MACHINE, 
		"SYSTEM\\CurrentControlSet\\Control\\GroupOrderList", ®_key); 
	if (status != ERROR_SUCCESS) { 
		fprintf(stderr, "RegOpenKey: %d\n", status); 
		return; 
	} 
 
	n = sizeof(tags); 
	status = RegQueryValueEx(reg_key, DRIVER_GROUP, NULL, &type, (LPBYTE)tags, &n); 
	if (status != ERROR_SUCCESS) { 
		fprintf(stderr, "RegQueryValueEx: %d\n", status); 
		return; 
	} 
 
	n /= sizeof(DWORD); 
 
	for (i = 1; i < n; i++) 
		if (tags[i] == service_tag) { 
			memmove(&tags[i], &tags[i + 1], (n - i - 1) * sizeof(DWORD)); 
			n--; 
			break; 
		} 
 
	tags[0] = n - 1; 
 
	status = RegSetValueEx(reg_key, DRIVER_GROUP, 0, type, (LPBYTE)tags, n * sizeof(DWORD)); 
	if (status != ERROR_SUCCESS) { 
		fprintf(stderr, "RegSetValueEx: %d\n", status); 
		return; 
	} 
 
	RegCloseKey(reg_key); 
 
	// remove service 
 
	if (!DeleteService(service)) { 
		if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE) { 
			fprintf(stderr, "DeleteService: %d\n", GetLastError()); 
			return; 
		} 
		printf("Restart Windows to changes has effect\n"); 
	} 
 
	CloseServiceHandle(service); 
	CloseServiceHandle(sch); 
 
	printf("success\n"); 
}