Sound Blaster 16 DOS/Windows 3.1 드라이버

설치시 IRQ 및 기타 정보들을 자동으로 감지하여 적용해줌.
실제 머신에서 테스트 완료 했음.
압축 파일을 보면 install 폴더내의 파일들만 디스켓으로 옮겨서 설치하시면 됨.
확인해보니 1.44MB 디스켓 한장에 들어감.

참고로 사블 16은 사블 2.0과 다르게 IRQ 셋팅 점퍼가 없어서..
(한참 보드를 쳐다봤음.. -_-)
드라이버를 통해서만 변경 및 셋팅이 가능하므로 반드시 설치해야함.

2

SB16_Dos_Install_Disks.rar

Sound Blaster 2.0 DOS 드라이버

사운드 블래스터 2.0 드라이버 설치 파일임.

자질구리하게 AUTOEXEC.BAT나 CONFIG.SYS 를 만질 필요 없이
설치시 IRQ 등 환경을 자동으로 감지하여 적용해 준다.
실제 머신에서 테스트 완료.

압축 파일내 4개의 디스켓 폴더가 보이는데,
1.44MB 디스켓 두장으로
첫번째 장엔 Disk 1, 2 폴더내의 파일들을..
두번째 장에는 Disk 3, 4 폴더내의 파일들을 복사하시면 됩니다.

1

Sound_Blaster_2.0_CT-1350B_Install_Disks.rar

윈도우즈 64비트 커널 드라이버 인증 절차

입력에 사용된 커맨드들은 WinDDK에 포함되어 있다.

인증대행 업체로부터 전달받은 두개의 파일(.pvk, .scr)을 아래의 명령대로 입력한다.
암호는 인증서를 받을때 인증 대행 업체에 알려주었던 비밀번호를 입력한다.

pvk2pfx -pvk "pvk파일" -pi "암호" -spc "spc파일" -pfx "회사이름.pfx" -po "암호" -f

.pfx 파일이 생성되었다.

다음 생성된 pfx 파일을 더블클하여 드라이버를 인증하기위한 PC에 등록한다.

첫번째, 두번째 스텝은 기본값으로 다음을 누른다.

세번째 스텝에서 암호 입력창에서 암호는 위 커맨드에서 입력하였던 비밀번호를 입력한다.

네번째 스텝에서는 “모든 인증서를 다음 저장소에 저장”을 클릭한후 “개인(my)”을 선택하여 저장한다.

이제 인증서 가져오기가 완료되었으므로 해당 PC에서 드라이버 인증을 할 수 있게 되었다.

참고로 등록된 인증서는 시작 -> 실행 -> certmgr.msc 를 실행하면 개인 -> 인증서 항목에서 볼 수 있다.

다음 마이크로 소프트사로 부터 해당 인증기관에 해당하는 크로스인증서를 다운로드 받는다.

http://www.microsoft.com/whdc/driver/install/drvsign/crosscert.mspx

참고로 나는 인증기관이 VeriSign 이므로 맨 아래에서 다운을 받았다.

다운 받은 파일을 실행해서 압축을 풀면 MSCV-VSClass3.cer 파일이 생기는데 이 파일은 드라이버를 인증할때 사용된다.

다음 마지막으로 드라이버를 인증한다.

signtool.exe sign /v /ac "MSCV-VSClass3.cer" /f "pfx파일" /p "암호" /t "http://timestamp.verisign.com/scripts/timestamp.dll" /d "드라이버설명문구" /du "드라이버제작사홈페이지URL" test.sys

참고로 타임스탬프는 반드시 받도록 하자.

타임스탬프를 받는 이유는 만약 인증서가 만료되면 해당 파일은 더이상 유효하지 않게 되지만,

타임스탬프를 받게 된다면 타임스탬프 받는 시기가 기준이 되어서 인증서가 만료되었다고 하더라도

파일이 유효하게 되어서 일반적으로 타임스탬프는 반드시 받는것이 좋다.

Windows 64비트로 드라이버 포팅

Windows 64비트로 드라이버 포팅 할 일이 생겼다.
아래의 문서와 링크를 참고한다.

윈도우 커널모드 드라이버 64비트 포팅.ppt

http://support.microsoft.com/kb/888728/ko

————–

64bit 플랫폼은 x64와 IA64가 있다.
IA64는 진정한 Real 64bit 운영체제를 위한 CPU로써 인텔 HP Microsoft의 공동 작품.
그리고 x64는 AMD에서 인텔의 64비트 프로세서에 대응하기 위해 Memory Addressing 영역을 2의 64승까지 늘린 프로세서.
IA64는 비싼가격이기에 보통 일반 유저는 사용하지 않는다.

————–

빌드시 error C2220: warning treated as error – no ‘object’ file generated 에러가 난다면 아래를 Sources 파일에 추가한다.

!if $(FREEBUILD)
MSC_WARNING_LEVEL=/W1
!else
MSC_WARNING_LEVEL=/W3
!endif

그래도 안되면.. /W1 부분을 /W0 으로 변경한다.

————–
64비트 드라이버는 반드시 인증을 거쳐야한다.
인증을 받지 않은 드라이버는 로딩조차 되지 않는다.

설치시 아래와 같은 화면이 뜬다.
ivory2

아래와 같이 사용할 수 없다.
ivory

개발시에는 테스트 모드로 부팅해서 개발이 가능하다.
하지만 어차피 인증은 받아야 하는데, 대략 1년에 40만원 정도라한다.
인증 방법은 여기, 여기 를 본다.

인증 업체는 아래와 같다.

Baltimore CyberTrust
Equifax Secure
GTE CyberTrust
GlobalSign
GeoTrust
VeriSign

——————
윈도우즈 7 테스트 모드로 변경 및 드라이버 파일(.sys) 에 테스트 사인 삽입 프로그램
(개발자들이 필요한 프로그램)

dseo13b.7z

sc

——————

아래는 64비트에 와서 갑자기 인증 방법이 왜 생겼는지에 대한 마소의 답변이다.

결론: 보안을 위해서 인증을 사용한다.

출처: http://www.driveronline.org/bbs/view.asp?tb=systembbs&no=12

대충의 내용을 살펴보면 아래와 같습니다.

Q. kernel-mode code signing을 하는 이유는 무엇이냐
커널 모드 code를 사용하는 악성코드가 많이 늘어났기 때문에

Q. 32Bit는 안하고 64Bit 에서만 하는 이유는?
32Bit를 할경우 이미 많은 드라이버가 설치 되어 있어서 문제가 많이 발생한다.
아주 적은 Driver 만이 64Bit에서 동작하고 있기 때문에 64Bit에서만 한다.

Q. 32Bit version을 가지고 있는데 signed 받아야 하나?
64Bit 모듈과 32Bit 모듈 둘다 제공 한다면 MS에서는 인증 받으라고 권하고 있다.

Q. 왜 그룹 Policy 적책으로 신뢰하게 하지 않는가
악성코드들이 이용할 수 있기 때문에 MS 에서는 허용하지 않는다.

Q. 왜 VeriSign 으로 부터 $499 짜리 인증서가 필요한가?
믿을만한 인증기관에서 인증을 받아야 한다고 한다. 전세계에 판매하는 Software에서 $499는 작은 돈이라고 한다.

Q. 왜 VeriSign만 되는가 다른 CA가 안되는 이유?
현재 MS가 OCA, WER 에서 VeriSign의 인증을 사용하고 있기 때문이고 다른 CA하고도 진행중이다.

Q. $500은 나에게 비싸다 다른 방법이 없겠나?
^^; 인증을 받는것이 더 좋다는 이야기 뿐이네요

Q. 이것은 DRM 적책의 시작인가?
아니다 보안과 품질을 향상 시키고자 하는 것이다.

Q. 왜 Windows Logo, DRS대신 signing 이 필요한 것인가?
Logo, DRS는 보안영역에 대한 보증을 하지 못한다 signing을 사용해야 한다.

————–
출처: http://www.driveronline.org/bbs/view.asp?tb=drivetc&no=948

H/W 를 사용하는 DeviceDriver 라면 WHQL 인증을 받으셔야 합니다.
(WHQL 인증방법: http://www.sinwoong.co.kr/144)
이것은 지금 DTM 으로 변경되었지요
결국 Microsoft 가 원하는 방식으로 Code 가 작성되고 동작하는지 검증을 받은 후 Microsoft 에서 해당 드라이버가 안전하다는 인증을 해주는 것 입니다.
그러나 파일 필터와 같이 장치를 사용하지 않는 드라이버에 대해서는 DTM 을 통하지 않고 SelfSing 을 진행 합니다.
필터 드라이버와 같이 자주 Update 하는 드라이버를 DTM 인증을 통하면 너무 많은 시간이 걸리기 때문에 다른 길을 열어 준 것 입니다.
방법은 Test sing 한 것과 비슷 합니다.
먼저 Microsoft 의 whdc 사이트에서 cross sign 을 지원하는 cross certification 을 지원하는 회사에서 인증서를 하나 구입하신 후 아래 site 에서 cross sing 인증서를 다운 받으신 후 구입하신 인증서와 cross 인증서를 사용하여 인증하시면 됩니다.
이 게시판에 인증에 대한 이야기가 있으므로 검색해보세요
그리고 보다 자세한 내용은 아래 사이트를 참고하세요

————–

바이너리 호환(.sys)은, 64bit 시스템에서 사용하는 드라이버는 64bit 컴파일러로 만든 바이너리 파일 이여야 한다.
32bit 컴파일러에서 만든 바이너리 파일은 응용프로그램에서는 wow64를 통해서 허용 되지만, 드라이버 파일에서는 허용되지 않는다.
반드시 64bit 컴파일러로 컴파일해서 사용한다.

libusb 초보자 가이드

이 문서는 libusb를 사용하고자 하는 분들을 위한 초보자 가이드이다.

시작하기

libusb는 커널 레벨이 아닌 유저 영역에서 USB 드라이버를 개발시 사용되는 오픈소스 라이브러리이다. libusb는 USB 호스트가 동작하지 않는다면 무용지물인 라이브러리이다. 이 글은 윈도우즈를 기준으로 설명한다.

inf 생성하기

이 글을 포스팅 하기 위해 다이나릿 시스템의 iNCITE 하드웨어를 이용하였다. iNCITE는 USB 2.0 호스트 인터페이스를 제공하는, FPGA 디자인을 검증하기 위한 Xilinx사의 Spratan과 그외 다양한 장치를 지원하는 디자인 검증 플랫폼이다 . 우선 위의 싸이트에서 libusb-win32-device-bin-xxx.tar.gz 와 libusb-win32-filter-bin-xxx.exe 를 다운 받는다. libusb-win32-filter-bin-xxx.exe 를 설치하고, Test Program 을 수행하면 현재 사용가능한 USB 장치가 나열된다.

1

다음 libusb-win32-device-bin-xxx.tar.gz 압축을 풀어, bin 디렉토리내의 inf-wizard.exe 를 수행한다. 이 단계에서 *.inf 파일을 생성한다. 우선 제작할 드라이버의 하드웨어를 켜준다.

2

위의 화면에서 보시는바와 같이 새로운 하드웨어(iNCITE) 가 보여질것이다. 선택후 다음 버튼을 눌러 Manfacture Name과 Device Name을 지정한다.

3

다음을 누르면 화면의 보여지는 정보로 지정한 위치로 *.inf 파일이 생성된다. 여기서는 D:\iVORY 로 지정하였다.

4

이제 생성된 *.inf 파일을 로딩해본다. 하드웨어를 리셋하면 새로운 USB 장치를 로딩하기위한 새 하드웨어 검색 마법사 화면이 나타난다.

5

다음 검색 안 함. 설치할 드라이버를 직접 선택을 선택한다.

6

다음 디스크 있음 을 선택하고, *.inf 파일이 저장된 위치를 선택한다.

7

설치치 libusb0.sys 파일을 요구하는데 libusb-win32-device-bin-xxx\bin 내의 libusb0.sys 파일을 지정한다.

8

설치가 완료된다. 이제 처음 수행했던 Test Program을 다시 실행한다.

9

장치 관리자 에서도 인식이 됨을 알 수 있다.

10

하드웨어가 인식되고, 하드웨어와 통신하는 코드를 작성 하기 위한 준비 단계는 완료되었다.

유저 프로그램 작성

libusb-win32-device-bin-xxx\examples 를 보면 기본 예제가 있다. 우선 작업 디렉토리인 D:\iVORY 로 위의 예제 파일인 bulk.c 를 복사한후 bulk.c 파일의 MY_VID와 MY_PIC 를 수정한다. 참고로 MY_VID는 Vendor ID, MY_PID는 Product ID 를 의미한다. 그외 usb_bulk_write, usb_bulk_read, usb_control_msg 를 사용하여 데이타를 송/수신한다. 아래의 예는 bulk.c 를 수정한 파일로 iNCITE의 카드 아이디(CID) 정보를 읽어낸다.

#include <usb.h>
#include <stdio.h>

/* the device's vendor and product id */
#define MY_VID 					0x1A89		// iNCITE
#define MY_PID 					0x3000		// iNCITE

/* the device's endpoints */
#define EP_IN 					0x81
#define EP_OUT 					0x01

#define BUF_SIZE 				64

#define	USB_DIR_IN				0x80
#define	USB_DIR_OUT				0x00

#define VENDOR_REQUEST_IVORY 	0x54		// iNCITE

usb_dev_handle *open_dev(void);

usb_dev_handle *open_dev(void)
{
	struct usb_bus *bus;
	struct usb_device *dev;

	for(bus = usb_get_busses(); bus; bus = bus->next)
	{
		for(dev = bus->devices; dev; dev = dev->next)
		{
			if(dev->descriptor.idVendor == MY_VID
				&& dev->descriptor.idProduct == MY_PID)
			{
				fprintf(stdout, "Found device: 0x%x:0x%x\n", MY_VID, MY_PID);
				fprintf(stdout, "Device filename: %s\n", dev->filename);
				fprintf(stdout, "Bus dirname: %s\n", bus->dirname);

				usb_dev_handle *fdev;
				fdev = usb_open(dev);

				char string[50];
				usb_get_string_simple(fdev, dev->descriptor.iManufacturer, string, sizeof(string));
				fprintf(stdout, "Device Manfucaturer : %s\n" ,string);
				usb_get_string_simple(fdev, dev->descriptor.iProduct, string, sizeof(string));
				fprintf(stdout, "Product Name : %s\n", string);
				usb_get_string_simple(fdev, dev->descriptor.iSerialNumber, string, sizeof(string));
				fprintf(stdout, "Device Serial Number: %s\n", string);

				return fdev;
			}
		}
	}

	return NULL;
}

// Device I/O control
int ivory_get_cid(usb_dev_handle *dev)		// iNCITE
{
	#define	HIU_CID					0x054

	int ret = 0;
	unsigned char buf[BUF_SIZE];

	ret = usb_control_msg(dev,
		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 	// __u8 requesttype
		VENDOR_REQUEST_IVORY, 								// __u8 request
		HIU_CID, 											// __u16 value
		0, 													// __u16 index
		buf, 												// void *data
		sizeof(int), 										// __u16 size
		5000 												// int timeout
	);

	return *buf;
}

int main(void)
{
	usb_dev_handle *dev = NULL; /* the device handle */

	usb_init(); /* initialize the library */
	usb_find_busses(); /* find all busses */
	usb_find_devices(); /* find all connected devices */

	if(!(dev = open_dev()))
	{
		printf("error: device not found!\n");
		return 0;
	}

	if(usb_set_configuration(dev, 1) < 0)
	{
		printf("error: setting config 1 failed\n");
		usb_close(dev);
		return 0;
	}

	if(usb_claim_interface(dev, 0) < 0)
	{
		printf("error: claiming interface 0 failed\n");
		usb_close(dev);
		return 0;
	}

	// ---------------------------------------
	int cid;
	cid = ivory_get_cid(dev);

	fprintf(stdout, "CID: %d\n", cid);
	// ---------------------------------------

	usb_release_interface(dev, 0);
	usb_close(dev);

	return 0;
}

빌드 및 테스트

Makefile을 아래와 같이 간단히 작성한다.

all:
	gcc -g -o bulk.exe -I../libusb-win32-device-bin-0.1.12.1/include bulk.c ../libusb-win32-device-bin-0.1.12.1/lib/gcc/libusb.a

clean:
	rm -rf *.o *.exe

컴파일후 생성된 bulk.exe를 수행하면 iNCITE의 현재 CID 정보를 리턴한다.

[Administrator@MYMAIN /d/ivory]$ ./bulk.exe
Found device: 0x1a89:0x3000
Device filename: \\.\libusb0-0003--0x1a89-0x3000
Bus dirname: bus-0
Device Manfucaturer : Dynalith
Product Name : iVORY
Device Serial Number: ?
CID: 1

이 코드를 컴파일한 환경은 다음과 같다.

gcc.exe (GCC) 3.4.5 (mingw-vista special r3)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

libusb의 한계

  • USB 장치의 insert/remove 처리가 까다로울 수 있다.
  • libusb는 유저 레벨에서 제어하므로, 실시간 처리와 관계되는 isochronous transfer, interrupt transfer를 지원하기는 어려움이 있다. 즉, kernel module 없이 간단한 USB 장치를 제어하는데 좋다.