예제 #1
0
파일: tftpd.c 프로젝트: wsj-zz/FamesOS
/*----------------------------------------------------------------------------------------------
 * 函数:    tftpd_dispatcher()
 *
 * 说明:    TFTP数据包处理(启动处理任务)
 *
 * 输入:    1) ip_pkt         IP数据包
 *          2) pkt_len        数据包大小
**--------------------------------------------------------------------------------------------*/
void apical tftpd_dispatcher(INT08S *ip_pkt, INT16S pkt_len)
{
    static HANDLE tftpd_task = InvalidHandle-1;
    static INT08S * rx_buf = NULL;
    void __daemon tftpd_daemon(void * data);

    if(!ip_pkt)return;

    if(!rx_buf)
        allocate_buffer(rx_buf, INT08S *, (INT32U)TFTP_RX_BUF_SIZE, return);

    if(pkt_len > TFTP_RX_BUF_SIZE){
        pkt_len = TFTP_RX_BUF_SIZE;
    }
    if(tftp_packet_lock){
        return;
    }    
    DispatchLock();
    MEMCPY(rx_buf, ip_pkt, pkt_len);
    tftp_packet_received = 1;
    DispatchUnlock();
    if(tftpd_task == InvalidHandle-1){
        tftpd_task=TaskCreate(tftpd_daemon, (void *)rx_buf, "tftpd", NULL, 2048, PRIO_NET, TASK_CREATE_OPT_NONE);
    } else {
        TaskAwake(tftpd_task);
    }
}
예제 #2
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_DRAW_H_IMAGE()
 * 说明:    按颜色映象(IMAGE)水平画线
 * 输入:    x       起始横坐标(0~SCREEN.width-1)
 *          y       纵坐标(0~SCREEN.height-1)
 *          x2      结尾横坐标(0~SCREEN.width-1)
 *          colors  颜色映象(颜色数组)
 * 注意:    本函数专门针对1024x768x256进行了优化
 *          本函数主要用于显示图形(位图)
**----------------------------------------------------------------------------------*/
INT16S  X_DRAW_H_IMAGE(INT16S x, INT16S y, INT16S x2, COLOR colors[])
{
    if(x>x2){
        x += x2;
        x2 = x-x2;
        x -= x2;
    }
    if(SCREEN.opened!=TRUE)
        return fail;
    if(colors==NULL     )return fail;  
    if(y < 0            )return fail;
    if(y >=SCREEN.height)return fail;
    if(x >=SCREEN.width )return fail;
    if(x2< 0            )return fail;
    if(x < 0            )x = 0;
    if(x2>=SCREEN.width )x2= SCREEN.width-1;
    DispatchLock();
    asm push ax
    asm push bx
    asm push cx
    asm push dx
    asm push es
    asm push ds
    asm push di
    asm push si
    asm mov  di, y
    asm mov  dx, di
    asm shr  dx, 6
    asm cmp  dx, SCREEN.curr_page
    asm jz   do_putpixel
    asm mov  SCREEN.curr_page, dx
    asm mov  ax, 0x4F05
    asm mov  bx, 0
    asm int  0x10;
    do_putpixel:
    asm and  di, 0x3F                         /* 建立ES:DI */
    asm shl  di, 10
    asm add  di, x
    asm mov  ax, VIDEOSEG
    asm mov  es, ax
    asm lds  bx, dword ptr colors
    asm mov  si, bx                           /* 建立DS:SI */
    asm mov  cx, x2
    asm sub  cx, x
    asm inc  cx
    asm rep  movsb
    asm pop  si
    asm pop  di
    asm pop  ds
    asm pop  es
    asm pop  dx
    asm pop  cx
    asm pop  bx
    asm pop  ax
    DispatchUnlock();
    return ok;
}
예제 #3
0
파일: init.c 프로젝트: wsj-zz/FamesOS
/*----------------------------------------------------------------------------------------------
 * 函数:    ExitApplication()
 *
 * 说明:    退出应用程序的运行,此函数会将控制权交与ExitFamesOS(),并最终返回DOS
 *
 * 备注:    须使用此函数来退出应用程序
**--------------------------------------------------------------------------------------------*/
void apical ExitApplication(void)
{
    if(FamesOSStarted){
        DispatchLock();
        FamesOSStarted=NO;
        ExitAppFlag=YES;
        longjmp(JumpBuf, 1);
    }
}
예제 #4
0
파일: tcp.c 프로젝트: wsj-zz/FamesOS
/*----------------------------------------------------------------------------------------------
 * 函数:    tcp_dispatcher()
 *
 * 说明:    TCP数据包处理
 *
 * 输入:    1) ip_pkt         IP数据包
 *          2) pkt_len        数据包大小
**--------------------------------------------------------------------------------------------*/
void apical tcp_dispatcher(INT08S * buf, INT16S buf_len)
{
    FamesAssert(buf);

    buf_len = buf_len;
    
    #if 0
    static int i=0;
    DispatchLock();
    printf("tcp rxed %d\n", i++);
    DispatchUnlock();
    #endif
}
예제 #5
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_DRAW_H_LINE()
 * 说明:    画水平线
 * 输入:    x       起始横坐标(0~SCREEN.width-1)
 *          y       纵坐标(0~SCREEN.height-1)
 *          x2      结尾横坐标(0~SCREEN.width-1)
 *          color   线的颜色
 * 注意:    本函数专门针对1024x768x256进行了优化
**----------------------------------------------------------------------------------*/
INT16S  X_DRAW_H_LINE(INT16S x, INT16S y, INT16S x2, COLOR  color)
{
    if(x>x2){
        x += x2;
        x2 = x-x2;
        x -= x2;
    }
    if(SCREEN.opened!=TRUE)
        return fail;
    if(y < 0            )return fail;
    if(y >=SCREEN.height)return fail;
    if(x >=SCREEN.width )return fail;
    if(x2< 0            )return fail;
    if(x < 0            )x = 0;
    if(x2>=SCREEN.width )x2= SCREEN.width-1;
    DispatchLock();
    asm push ax
    asm push bx
    asm push cx
    asm push dx
    asm push es
    asm push di
    asm mov  di, y
    asm mov  dx, di
    asm shr  dx, 6
    asm cmp  dx, SCREEN.curr_page
    asm jz   do_putpixel
    asm mov  SCREEN.curr_page, dx
    asm mov  ax, 0x4F05
    asm mov  bx, 0
    asm int  0x10;
    do_putpixel:
    asm and  di, 0x3F
    asm shl  di, 10
    asm add  di, x
    asm mov  ax, VIDEOSEG
    asm mov  es, ax
    asm mov  al, color
    asm mov  cx, x2
    asm sub  cx, x
    asm inc  cx
    asm rep  stosb
    asm pop  di
    asm pop  es
    asm pop  dx
    asm pop  cx
    asm pop  bx
    asm pop  ax
    DispatchUnlock();
    return ok;
}
예제 #6
0
파일: tftpd.c 프로젝트: wsj-zz/FamesOS
/*----------------------------------------------------------------------------------------------
 * 函数:    tftpd_xmit()
 *
 * 说明:    发送tftp报文
 *
 * 输入:    1) target_ip     目标ip地址
 *          2) target_port   目标端口
 *          3) opcode        tftp操作码
 *          4) blkid         数据块号(或错误码)
 *          5) buf           数据(或错误信息)
 *          6) buf_len       数据长度
 *
 * 返回:    ok/fail
**--------------------------------------------------------------------------------------------*/
BOOL apical tftpd_xmit(INT32U target_ip, INT16U target_port, INT16U opcode, 
                       INT16U blkid, INT08S *buf, INT16U buf_len)
{
    static INT08S * tx_buf = NULL;
    struct tftphdr * hdr;

    if(!tx_buf)
        allocate_buffer(tx_buf, INT08S *, (INT32U)TFTP_TX_BUF_SIZE, return fail);

    hdr = (struct tftphdr *)tx_buf; /*lint !e826 */

    #if 0
    DispatchLock();
    printf("\ntftpd_xmit: target_ip=%08lX, port=%d, opcode=%d, blkid=%d, buf=%s, buf_len=%d",
        target_ip, target_port, opcode, blkid, buf, buf_len);
    DispatchUnlock();
    #endif

    switch(opcode){
        case TFTP_OP_RRQ:
        case TFTP_OP_WRQ:
            return fail;
        case TFTP_OP_DAT:
            FamesAssert(buf);
            hdr->opcode = INT16XCHG(opcode);
            hdr->un.id  = INT16XCHG(blkid);
            MEMCPY(&tx_buf[4], buf, (INT16S)buf_len);
            buf_len+=4;
            break;
        case TFTP_OP_ACK:
            hdr->opcode = INT16XCHG(opcode);
            hdr->un.id  = INT16XCHG(blkid);
            buf_len=4;
            break;
        case TFTP_OP_ERR:
            FamesAssert(buf);
            hdr->opcode = INT16XCHG(opcode);
            hdr->un.err.err  = INT16XCHG(blkid);
            MEMCPY(&tx_buf[4], buf, (INT16S)buf_len);
            buf_len+=4;
            break;
        default:
            return fail;
    }
    return send_udp(target_ip, target_port, UDP_P_TFTP, tx_buf, buf_len);

}
예제 #7
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_SET_PALETTE()
 * 说明:    设置某一颜色的调色板
 * 输入:    index   颜色值(0~255)
 *          red     红色分量(0~63)
 *          green   绿色分量(0~63)
 *          blue    蓝色分量(0~63)
 * 输出:    ok/fail
**----------------------------------------------------------------------------------*/
INT16S  X_SET_PALETTE(INT16S index, INT08U  red, INT08U  grn, INT08U  blue)
{
    if(index>=256){
        return fail;
    }
    if((INT16S)red  >63)red  =63;
    if((INT16S)grn  >63)grn  =63;
    if((INT16S)blue >63)blue =63;
    DispatchLock();
    outportbyte(0x3c8,(INT08U)index);
    outportbyte(0x3c9,red  );
    outportbyte(0x3c9,grn  );
    outportbyte(0x3c9,blue );
    DispatchUnlock();
    FamesDelay(10L);
    return ok;
}
예제 #8
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_CLOSE_GRAPH()
 * 说明:    关闭图形模式(回到文本模式)
**----------------------------------------------------------------------------------*/
INT16S  X_CLOSE_GRAPH()
{
    if(SCREEN.opened!=TRUE){
        return ok;
    }
    DispatchLock();
    asm push ax
    asm push bx
    asm mov ax,0x4F02;
    asm mov bx,VMODE_TEXT;
    asm int 0x10;
    asm pop bx
    asm pop ax
    SCREEN.opened=FALSE;
    DispatchUnlock();
    return ok;
}
예제 #9
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_OPEN_GRAPH()
 * 说明:    打开图形模式
**----------------------------------------------------------------------------------*/
INT16S  X_OPEN_GRAPH(void)
{
    INT16S vmode;
    if(SCREEN.opened==TRUE){
        return ok;
    }
    DispatchLock();
    vmode=SCREEN.videomode;
    vmode=vmode;
    asm push ax
    asm push bx
    asm mov ax,0x4F02;
    asm mov bx,vmode;
    asm int 0x10;
    asm pop bx
    asm pop ax
    SCREEN.opened=TRUE;
    X_SET_PALETTE_DEFAULT();
    DispatchUnlock();
    return ok;
}
예제 #10
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_GET_PIXEL()
 * 说明:    在指定位置读一个点的颜色
 * 输入:    x       横坐标(0~SCREEN.width-1)
 *          y       纵坐标(0~SCREEN.height-1)
 * 输出:    color   点的颜色
 * 注意:    本函数专门针对1024x768x256进行了优化
**----------------------------------------------------------------------------------*/
COLOR   X_GET_PIXEL(INT16S x, INT16S y)
{
    register INT08U  color;
    
    if(x<0 || x>=SCREEN.width || y<0 || y>=SCREEN.height){
        return fail;
    }
    if(SCREEN.opened!=TRUE)
        return fail;
    DispatchLock();
    asm push ax
    asm push bx
    asm push dx
    asm push ds
    asm push si
    asm mov  si, y
    asm mov  dx, si
    asm shr  dx, 6
    asm cmp  dx, SCREEN.curr_page
    asm jz   do_getpixel
    asm mov  SCREEN.curr_page, dx
    asm mov  ax, 0x4F05
    asm mov  bx, 0
    asm int  0x10;
    do_getpixel:
    asm and  si, 0x3f
    asm shl  si, 10
    asm add  si, x
    asm mov  ax, VIDEOSEG
    asm mov  ds, ax
    asm lodsb
    asm mov  color, al
    asm pop si
    asm pop ds
    asm pop dx
    asm pop bx
    asm pop ax
    DispatchUnlock();
    return color; /*lint !e530*/
}
예제 #11
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_PUT_PIXEL()
 * 说明:    在指定位置画一个点
 * 输入:    x       横坐标(0~SCREEN.width-1)
 *          y       纵坐标(0~SCREEN.height-1)
 *          color   点的颜色
 * 输出:    ok/fail
 * 注意:    本函数专门针对1024x768x256进行了优化
**----------------------------------------------------------------------------------*/
INT16S  X_PUT_PIXEL(INT16S x, INT16S y, COLOR  color)
{
    if(x<0 || x>=SCREEN.width || y<0 || y>=SCREEN.height){
        return fail;
    }
    if(SCREEN.opened!=TRUE)
        return fail;
    DispatchLock();
    asm push ax
    asm push bx
    asm push dx
    asm push es
    asm push di
    asm mov  di, y
    asm mov  dx, di
    asm shr  dx, 6
    asm cmp  dx, SCREEN.curr_page
    asm jz   do_putpixel
    asm mov  SCREEN.curr_page, dx
    asm mov  ax, 0x4F05
    asm mov  bx, 0
    asm int  0x10;
    do_putpixel:
    asm and  di, 0x3f
    asm shl  di, 10
    asm add  di, x
    asm mov  ax, VIDEOSEG
    asm mov  es, ax
    asm mov  al, color
    asm stosb
    asm pop di
    asm pop es
    asm pop dx
    asm pop bx
    asm pop ax
    DispatchUnlock();
    return ok;
}
예제 #12
0
파일: bmp.c 프로젝트: wsj-zz/FamesOS
/*----------------------------------------------------------------------------------------------
 * 函数:    GetBmpPalette()
 * 说明:    取指定BMP文件中的调色板
 * 输入:    palette 调色板缓冲区
 *          bmpfile BMP文件名 
 * 注意:    本函数只是将BMP文件中的调色板原封不动的放到palette中去,
 *          所以要求palette缓冲一定要大于1024字节,否则将会得到不可预料的结果.
**--------------------------------------------------------------------------------------------*/
BOOLEAN apical GetBmpPalette(INT08U palette[], FILENAME bmpfile)
{
    int  fd;

    if(!palette){
        return fail;
    }
    if(!bmpfile){
        return fail;
    }
    DispatchLock();
    fd=open(bmpfile,O_RDONLY|O_BINARY);/*lint !e569*/
    if(fd < 0){
        DispatchUnlock();
        return fail;
    }
    read(fd, palette, sizeof(BmpCoreInfo));
    read(fd, palette, sizeof(BmpInfoHeader));
    read(fd, palette, 1024);
    close(fd);
    DispatchUnlock();
    return ok;
}
예제 #13
0
파일: tftpd.c 프로젝트: wsj-zz/FamesOS
/*----------------------------------------------------------------------------------------------
 * 函数:    get_tftpd_message()
 *
 * 说明:    读取一个tftpd消息
 *
 * 输入:    1) dst_message_buf  destination buffer
 *
 * 返回:    dst_message_buf/NULL for no messages
**--------------------------------------------------------------------------------------------*/
INT08S * apical get_tftpd_message(INT08S * dst_message_buf)
{
    static INT08S t_s[130];
    FamesAssert(dst_message_buf);

    if(!dst_message_buf){
        return NULL;
    }
    
    DispatchLock();
    if(tftpd_message.number <= 0){
        DispatchUnlock();
        return NULL;
    }
    STRCPY(t_s, tftpd_message.buf[tftpd_message.out]);
    STRCPY(dst_message_buf, t_s);
    tftpd_message.out++;
    tftpd_message.number--;
    tftpd_message.out%=TFTP_MESSAGE_BUF_NUM;
    DispatchUnlock();
    
    return dst_message_buf;    
}
예제 #14
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_DRAW_V_BITMAP_BGMAP()
 * 说明:    根据bitmap中的位画点(纵向), 如果某位为1,则在对应位置以color画点,
 *          否则以bgcolors中的颜色画点, 一次最多画8个点.
 * 输入:    x        起始横坐标(0~SCREEN.width-1)
 *          y        纵坐标(0~SCREEN.height-1)
 *          bitmap   一个字节的位模式
 *          color    颜色
 *          bgcolors 背景颜色
 * 注意:    本函数专门针对1024x768x256进行了优化
 * 用途:    本函数可大大加快字体的显示, 可用于画虚线
 *          在需要画背景图形的时候非常有用
**----------------------------------------------------------------------------------*/
INT16S  X_DRAW_V_BITMAP_BGMAP(INT16S x, INT16S y, INT08U bitmap, COLOR  color, COLOR bgcolors[])
{/*lint --e{529}*/
    INT16S bgc_index=0;

    if(x<0 || x>=SCREEN.width || y<0 || y>=SCREEN.height){
        return fail;
    }
    if(SCREEN.opened!=TRUE)
        return fail;
    DispatchLock();
    asm push ax
    asm push bx
    asm push cx
    asm push dx
    asm push es
    asm push di
    asm push si
    _SI=SCREEN.height; /*lint !e40 !e63*/
    asm mov  di, y
    asm mov  dx, di
    asm shr  dx, 6
    asm cmp  dx, SCREEN.curr_page
    asm jz   do_putpixel
    asm mov  SCREEN.curr_page, dx
    asm mov  ax, 0x4F05
    asm mov  bx, 0
    asm int  0x10;
    do_putpixel:
    asm and  di, 0x3F
    asm shl  di, 10
    asm add  di, x
    asm mov  ax, VIDEOSEG
    asm mov  es, ax
    asm mov  cx, 8
    asm mov  bx, y
    do_color_stosb:
    asm mov  ah, bitmap
    do_loop_start:
    asm cmp  bx, si
    asm jae  do_loop_end
    asm shl  ah, 1
    asm mov  al, color
    asm jc   do_put_dot
    asm  push es
    asm  push bx
    asm  les  bx, dword ptr bgcolors
    asm  add  bx, word ptr bgc_index
    asm  mov  al, byte ptr es:[bx]
    asm  pop  bx
    asm  pop  es
    do_put_dot:
    asm stosb
    asm inc  word ptr bgc_index
    asm and  di, di                           /* 以防在x=1023时出错                 */
    asm jz   do_change_page1
    asm add  di, 1023
    asm jc   do_change_page2
    do_jmp_loop:
    asm inc  bx
    asm loop do_loop_start
    do_loop_end:
    asm jmp  draw_v_bitmap_end
    do_change_page1:
    asm add  di, 1023
    do_change_page2:
    asm push ax
    asm inc  dx
    asm mov  SCREEN.curr_page, dx
    asm mov  ax, 0x4F05
    asm mov  bx, 0
    asm int  0x10;
    asm pop  ax
    asm jmp  do_jmp_loop
    draw_v_bitmap_end:
    asm pop  si
    asm pop  di
    asm pop  es
    asm pop  dx
    asm pop  cx
    asm pop  bx
    asm pop  ax
    DispatchUnlock();
    return ok;
}
예제 #15
0
파일: dokan.c 프로젝트: justsoso8/dokany
UINT WINAPI
DokanLoop(
   PDOKAN_INSTANCE DokanInstance
	)
{
	HANDLE	device;
	char	buffer[EVENT_CONTEXT_MAX_SIZE];
	BOOL	status;
	ULONG	returnedLength;
	DWORD	result = 0;
    DWORD   lastError = 0;
	RtlZeroMemory(buffer, sizeof(buffer));

	device = CreateFile(
				GetRawDeviceName(DokanInstance->DeviceName), // lpFileName
				GENERIC_READ | GENERIC_WRITE,       // dwDesiredAccess
				FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
				NULL,                               // lpSecurityAttributes
				OPEN_EXISTING,                      // dwCreationDistribution
				0,                                  // dwFlagsAndAttributes
				NULL                                // hTemplateFile
			);

	if (device == INVALID_HANDLE_VALUE) {
		DbgPrint("Dokan Error: CreateFile failed %ws: %d\n",
			GetRawDeviceName(DokanInstance->DeviceName), GetLastError());
		result = (DWORD)-1;
		_endthreadex(result);
		return result;
	}

	status = TRUE;
	while (status) {

		status = DeviceIoControl(
					device,				// Handle to device
					IOCTL_EVENT_WAIT,	// IO Control code
					NULL,				// Input Buffer to driver.
					0,					// Length of input buffer in bytes.
					buffer,             // Output Buffer from driver.
					sizeof(buffer),		// Length of output buffer in bytes.
					&returnedLength,	// Bytes placed in buffer.
					NULL                // synchronous call
					);

		if (!status) {
            lastError = GetLastError();
			DbgPrint("Ioctl failed for wait with code %d.\n", lastError);
            if (lastError == ERROR_NO_SYSTEM_RESOURCES) {
                DbgPrint("Processing will continue\n");
                status = TRUE;
                Sleep(200);
                continue;
            }
            DbgPrint("Thread will be terminated\n");
			break;
		}

		//printf("#%d got notification %d\n", (ULONG)Param, count++);

		if(returnedLength > 0) {
			PEVENT_CONTEXT context = (PEVENT_CONTEXT)buffer;
			if (context->MountId != DokanInstance->MountId) {
				DbgPrint("Dokan Error: Invalid MountId (expected:%d, acctual:%d)\n",
						DokanInstance->MountId, context->MountId);
				continue;
			}

			switch (context->MajorFunction) {
			case IRP_MJ_CREATE:
				DispatchCreate(device, context, DokanInstance);
				break;
			case IRP_MJ_CLEANUP:
				DispatchCleanup(device, context, DokanInstance);
				break;
			case IRP_MJ_CLOSE:
				DispatchClose(device, context, DokanInstance);
				break;
			case IRP_MJ_DIRECTORY_CONTROL:
				DispatchDirectoryInformation(device, context, DokanInstance);
				break;
			case IRP_MJ_READ:
				DispatchRead(device, context, DokanInstance);
				break;
			case IRP_MJ_WRITE:
				DispatchWrite(device, context, DokanInstance);
				break;
			case IRP_MJ_QUERY_INFORMATION:
				DispatchQueryInformation(device, context, DokanInstance);
				break;
			case IRP_MJ_QUERY_VOLUME_INFORMATION:
				DispatchQueryVolumeInformation(device ,context, DokanInstance);
				break;
			case IRP_MJ_LOCK_CONTROL:
				DispatchLock(device, context, DokanInstance);
				break;
			case IRP_MJ_SET_INFORMATION:
				DispatchSetInformation(device, context, DokanInstance);
				break;
			case IRP_MJ_FLUSH_BUFFERS:
				DispatchFlush(device, context, DokanInstance);
				break;
			case IRP_MJ_QUERY_SECURITY:
				DispatchQuerySecurity(device, context, DokanInstance);
				break;
			case IRP_MJ_SET_SECURITY:
				DispatchSetSecurity(device, context, DokanInstance);
				break;
			case IRP_MJ_SHUTDOWN:
				// this case is used before unmount not shutdown
				DispatchUnmount(device, context, DokanInstance);
				break;
			default:
				break;
			}

		} else {
			DbgPrint("ReturnedLength %d\n", returnedLength);
		}
	}

	CloseHandle(device);
    _endthreadex(result);

	return result;
}
예제 #16
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_DRAW_V_LINE()
 * 说明:    按颜色映象(IMAGE)垂直画线
 * 输入:    x       横坐标(0~SCREEN.width-1)
 *          y       起始纵坐标(0~SCREEN.height-1)
 *          y2      结尾纵坐标(0~SCREEN.height-1)
 *          colors  颜色映象(颜色数组)
 * 注意:    本函数专门针对1024x768x256进行了优化
 *          本函数主要用于显示图形(位图)
**----------------------------------------------------------------------------------*/
INT16S  X_DRAW_V_IMAGE(INT16S x, INT16S y, INT16S y2, COLOR colors[])
{/*lint --e{529}*/
    INT16S  c_index=0;
    if(y>y2){
        y += y2;
        y2 = y-y2;
        y -= y2;
    }
    if(SCREEN.opened!=TRUE)
        return fail;
    if(colors==NULL     )return fail;  
    if(x < 0            )return fail;
    if(x >=SCREEN.width )return fail;
    if(y >=SCREEN.height)return fail;
    if(y2< 0            )return fail;
    if(y < 0            )y = 0;
    if(y2>=SCREEN.height)y2= SCREEN.height-1;
    DispatchLock();
    asm push ax
    asm push bx
    asm push cx
    asm push dx
    asm push es
    asm push di
    asm mov  cx, y2
    asm sub  cx, y
    asm inc  cx
    asm mov  di, y
    asm mov  dx, di
    asm shr  dx, 6
    asm cmp  dx, SCREEN.curr_page
    asm jz   do_putpixel
    asm mov  SCREEN.curr_page, dx
    asm mov  ax, 0x4F05
    asm mov  bx, 0
    asm int  0x10;
    do_putpixel:
    asm and  di, 0x3f
    asm shl  di, 10
    asm add  di, x
    asm mov  ax, VIDEOSEG
    asm mov  es, ax
    do_color_stosb:
    asm  push es
    asm  push bx
    asm  les  bx, dword ptr colors
    asm  add  bx, word ptr c_index
    asm  mov  al, byte ptr es:[bx]
    asm  pop  bx
    asm  pop  es
    do_stosb:
    asm stosb
    asm inc  word ptr c_index
    asm dec  cx
    asm jz   draw_v_line_end
    asm inc  word ptr y
    asm and  di, di                           /* 以防在x=1023时出错 */
    asm jz   do_change_page1
    asm add  di, 1023
    asm jc   do_change_page2
    asm jmp  do_color_stosb
    do_change_page1:
    asm add  di, 1023
    do_change_page2:
    asm inc  dx
    asm mov  SCREEN.curr_page, dx
    asm mov  ax, 0x4F05
    asm mov  bx, 0
    asm int  0x10;
    asm jmp  do_color_stosb
    draw_v_line_end:
    asm pop  di
    asm pop  es
    asm pop  dx
    asm pop  cx
    asm pop  bx
    asm pop  ax
    DispatchUnlock();
    return ok;
}
예제 #17
0
파일: bmp.c 프로젝트: wsj-zz/FamesOS
/*----------------------------------------------------------------------------------------------
 * 函数:    LoadBmp()
 * 说明:    加载BMP文件中的图象到XMS, 并对应设置BMPINFO结构
 * 输入:    bmpinfo BMPINFO对象指针
 *          bmpfile BMP文件名
**--------------------------------------------------------------------------------------------*/
BOOLEAN apical LoadBmp(BMPINFO * bmpinfo, FILENAME bmpfile)
{
    BmpCoreInfo   bmpcoreinfo;
    BmpInfoHeader bmpinfoheader;
    int           fd;
    XMSHANDLE     handle;
    INT16U        bytesofline;
    INT16U        i;
    
    if(!bmpinfo){
        return fail;
    }
    if(!bmpfile){
        return fail;
    }
    if(bmpinfo->ready!=FAMES_BMP_READY_NO){
        return fail;
    }
    DispatchLock();
    fd=open(bmpfile,O_RDONLY|O_BINARY);/*lint !e569*/
    DispatchUnlock();
    if(fd < 0){
        return fail;
    }
    DispatchLock();
    read(fd, (void *)&bmpcoreinfo, sizeof(BmpCoreInfo));
    DispatchUnlock();
    if((bmpcoreinfo.identifier[0]!='B')||(bmpcoreinfo.identifier[1]!='M')){
        DispatchLock();
        close(fd);
        DispatchUnlock();
        return fail;        
    }
    DispatchLock();
    read(fd, (void *)&bmpinfoheader, sizeof(BmpInfoHeader));
    DispatchUnlock();
    switch(bmpinfoheader.bits_per_pixel){
        case 8:
            handle=XMSalloc((INT16U)bmpinfoheader.height+1);
            if(!handle){
                DispatchLock();
                close(fd);
                DispatchUnlock();
                return fail;
            }
            if(bmpinfoheader.height!=0L){
                bytesofline=(INT16U)(bmpinfoheader.bitmap_data_size/bmpinfoheader.height);
            } else {
                DispatchLock();
                close(fd);
                DispatchUnlock();
                return fail;                
            }
            DispatchLock();
            lseek(fd, (INT32S)bmpcoreinfo.bitmap_data_offset, SEEK_SET);
            DispatchUnlock();
            for(i=(INT16U)bmpinfoheader.height-1; (INT16S)i>=0; i--){                                
                DispatchLock();
                if(eof(fd)){
                    close(fd); 
                    DispatchUnlock();
                    return fail; 
                }
                read(fd, (void *)BMPCACHE, bytesofline);
                DispatchUnlock();
                if(!XMSput(handle, (void *)((INT32U)i<<10L), (void *)BMPCACHE, 1024L)){
                    ;
                }
            }
            DispatchLock();
            close(fd); 
            DispatchUnlock();
            bmpinfo->colordepth  = FAMES_BMP_CD_8;
            bmpinfo->width       = (INT16S)bmpinfoheader.width;
            bmpinfo->height      = (INT16S)bmpinfoheader.height;
            bmpinfo->maxwidth    = 0;
            bmpinfo->maxheight   = 0;
            bmpinfo->bytesofline = (INT16S)bytesofline;
            bmpinfo->handle      = handle;
            bmpinfo->ready       = FAMES_BMP_READY_YES;
            break;
        default:
            DispatchLock();
            close(fd);
            DispatchUnlock();
            return fail;
    }
    return ok;
}
예제 #18
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_DRAW_H_BITMAP_BG()
 * 说明:    根据bitmap中的位画点(横向), 如果某位为1,则在对应位置以color画点,
 *          否则以bgcolor画点, 一次最多画8个点.
 * 输入:    x       起始横坐标(0~SCREEN.width-1)
 *          y       纵坐标(0~SCREEN.height-1)
 *          dots    画点的个数
 *          bitmap  一个字节的位模式
 *          color   颜色
 *          bgcolor 背景颜色
 * 注意:    本函数专门针对1024x768x256进行了优化
 * 用途:    本函数可大大加快字体的显示, 可用于画虚线
 *          在需要画背景色的时候非常有用
**----------------------------------------------------------------------------------*/
INT16S  X_DRAW_H_BITMAP_BG(INT16S x, INT16S y, INT16S dots, INT08U bitmap, COLOR  color, COLOR bgcolor)
{
    if(x<0 || x>=SCREEN.width || y<0 || y>=SCREEN.height){
        return fail;
    }
    if(SCREEN.opened!=TRUE)
        return fail;
    if(dots > 8)
        dots=8;
    if(dots <= 0)
        return fail;
    DispatchLock();
    asm push ax
    asm push bx
    asm push cx
    asm push dx
    asm push es
    asm push di
    asm push si
    _SI=SCREEN.width; /*lint !e40 !e63*/
    asm mov  di, y
    asm mov  dx, di
    asm shr  dx, 6
    asm cmp  dx, SCREEN.curr_page
    asm jz   do_putpixel
    asm mov  SCREEN.curr_page, dx
    asm mov  ax, 0x4F05
    asm mov  bx, 0
    asm int  0x10;
    do_putpixel:
    asm and  di, 0x3F
    asm shl  di, 10
    asm add  di, x
    asm mov  ax, VIDEOSEG
    asm mov  es, ax
    asm mov  dl, color
    asm mov  dh, bgcolor
    asm mov  ah, bitmap
    asm mov  cx, dots
    asm mov  bx, x
    do_loop_start:
    asm cmp  bx, si
    asm jae  do_loop_end
    asm shl  ah, 1
    asm mov  al, dl
    asm jc   do_put_dot
    asm mov  al, dh
    do_put_dot:
    asm stosb
    asm inc  bx
    asm loop do_loop_start
    do_loop_end:
    asm pop  si
    asm pop  di
    asm pop  es
    asm pop  dx
    asm pop  cx
    asm pop  bx
    asm pop  ax
    DispatchUnlock();
    return ok;
}
예제 #19
0
파일: vesa.c 프로젝트: wsj-zz/FamesOS
/*------------------------------------------------------------------------------------
 * 函数:    X_DRAW_H_BITMAP_BGMAP()
 * 说明:    根据bitmap中的位画点(横向), 如果某位为1,则在对应位置以color画点,
 *          否则以bgcolors中的颜色画点, 一次最多画8个点.
 * 输入:    x        起始横坐标(0~SCREEN.width-1)
 *          y        纵坐标(0~SCREEN.height-1)
 *          bitmap   一个字节的位模式
 *          color    颜色
 *          bgcolors 背景颜色
 * 注意:    本函数专门针对1024x768x256进行了优化
 * 用途:    本函数可大大加快字体的显示, 可用于画虚线
 *          在需要画背景图形的时候非常有用
**----------------------------------------------------------------------------------*/
INT16S  X_DRAW_H_BITMAP_BGMAP(INT16S x, INT16S y, INT16S dots, INT08U bitmap, COLOR  color, COLOR bgcolors[])
{/*lint --e{529}*/
    INT16S bgc_index=0;
    
    if(x<0 || x>=SCREEN.width || y<0 || y>=SCREEN.height){
        return fail;
    }
    if(SCREEN.opened!=TRUE)
        return fail;
    if(dots > 8)
        dots=8;
    if(dots <= 0)
        return fail;
    if(bgcolors==NULL){
        return X_DRAW_H_BITMAP(x, y, dots, bitmap, color); /* 如果没有背景颜色,则不画背景色 */
    }
    DispatchLock();
    asm push ax
    asm push bx
    asm push cx
    asm push dx
    asm push es
    asm push di
    asm push si
    _SI=SCREEN.width; /*lint !e40 !e63*/
    asm mov  di, y
    asm mov  dx, di
    asm shr  dx, 6
    asm cmp  dx, SCREEN.curr_page
    asm jz   do_putpixel
    asm mov  SCREEN.curr_page, dx
    asm mov  ax, 0x4F05
    asm mov  bx, 0
    asm int  0x10;
    do_putpixel:
    asm and  di, 0x3F
    asm shl  di, 10
    asm add  di, x
    asm mov  ax, VIDEOSEG
    asm mov  es, ax
    asm mov  dl, color
    asm mov  ah, bitmap
    asm mov  cx, dots
    asm mov  bx, x
    do_loop_start:
    asm cmp  bx, si
    asm jae  do_loop_end
    asm shl  ah, 1
    asm mov  al, dl
    asm jc   do_put_dot
    asm push es
    asm push bx
    asm les  bx, dword ptr bgcolors
    asm add  bx, word ptr bgc_index
    asm mov  al, byte ptr es:[bx]
    asm pop  bx
    asm pop  es
    do_put_dot:
    asm stosb
    asm inc  word ptr bgc_index
    asm inc  bx
    asm loop do_loop_start
    do_loop_end:
    asm pop  si
    asm pop  di
    asm pop  es
    asm pop  dx
    asm pop  cx
    asm pop  bx
    asm pop  ax
    DispatchUnlock();
    return ok;
}
예제 #20
0
파일: tftpd.c 프로젝트: wsj-zz/FamesOS
/*----------------------------------------------------------------------------------------------
 * 函数:    tftpd_daemon()
 *
 * 描述:    tftp服务器的后台任务, 堆栈大小建议为2048
**--------------------------------------------------------------------------------------------*/
void __daemon tftpd_daemon(void * data)
{
    struct iphdr * ip_hdr;
    struct udphdr * u_hdr;
    struct tftphdr * hdr;
    INT16U tftp_len;
    INT16U binary_mode = 0;
    FILE * volatile fp=NULL;
    INT16U last_blk=0, bytes=0, blksn=0, blksn_old=0;
    INT32U ip_connect = 0L;
    INT16U remote_port = 0;
    INT16S timeout_resend = 0;
    INT08S filename[256], mode[10], buf[512];
    INT08S wbuf[512];
    void __internal __tx_timeout_for_tftpd(void *, INT16S);
    void __internal __rx_timeout_for_tftpd(void *, INT16S);

    FamesAssert(data);

    TimerSet(TimerTftpdTX, 1000L, TIMER_TYPE_AUTO, __tx_timeout_for_tftpd, (void *)CurrentTask);
    TimerStop(TimerTftpdTX);
    TimerSet(TimerTftpdRX, 30000L, TIMER_TYPE_AUTO, __rx_timeout_for_tftpd, (void *)CurrentTask);
    TimerStop(TimerTftpdRX);
    /*lint --e{613}*/
     
    do {
        if(timeout_wait_ack){ /* 超时重传 */
            timeout_wait_ack = 0;
            set_tftpd_message(TFTP_OP_XXX, 0, "wait ack timeout!", NULL, ip_connect);
            timeout_resend++;
            if(timeout_resend > 10){ /* 这么久还没收到,那就不管了 */
                TimerStop(TimerTftpdTX);
                timeout_wait_ack = 0;
                binary_mode = 0;
                if(fp){
                    DispatchLock();
                    fclose(fp);
                    fp=NULL;
                    DispatchUnlock();
                }
                ip_connect = 0L;
                timeout_resend = 0;
                goto i_will_take_a_nap;
            }
            if(!fp || ip_connect==0L){
                TimerStop(TimerTftpdTX);
                timeout_wait_ack = 0;
                goto i_will_take_a_nap;
            }
            tftpd_xmit(ip_connect, remote_port, TFTP_OP_DAT, blksn, buf, bytes);
            TimerReStart(TimerTftpdTX);
            goto i_will_take_a_nap;
        }

        if(timeout_wait_rx){   /* 等待客户端数据包超时 */
            TimerStop(TimerTftpdRX);
            timeout_wait_rx = 0;
            set_tftpd_message(TFTP_OP_XXX, 0, "wait client timeout(30sec)!", NULL, ip_connect);
            binary_mode = 0;
            if(fp){
                DispatchLock();
                fclose(fp);
                fp=NULL;
                DispatchUnlock();
            }
            ip_connect = 0L;                     
        }    
        
        if(tftp_packet_received==0)goto i_will_take_a_nap;
        tftp_packet_received=0;

        tftp_packet_lock = 1;
        
        ip_hdr = (struct iphdr *)data; /*lint !e826 */
        u_hdr  = (struct udphdr *)((INT08S *)data + (ip_hdr->ihl<<2)); /*lint !e826 !e613 */
        hdr    = (struct tftphdr *)((INT08S *)u_hdr+8); /*lint !e826 */

        tftp_len = INT16XCHG(u_hdr->len)-8; /* TFTP报文长度 */

        if(ip_hdr->daddr == get_bcast_ip()){ /*lint !e613 */
            goto i_will_take_a_nap;
        }

        if(ip_connect!=0L){
            if(ip_connect != ip_hdr->saddr){ /*lint !e613*/
                set_tftpd_message(TFTP_OP_XXX, 0, "not the client ip packet", NULL, ip_hdr->saddr); /*lint !e613*/
                tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ERR, 0, 
                                "I am busy, please wait a moment!!!", 35); /*lint !e613*/
                goto i_will_take_a_nap;
            }
        }

        TimerReStart(TimerTftpdRX); /* 接收到了客户端的数据包, 则重设定时器 */

        switch(INT16XCHG(hdr->opcode)){
            case TFTP_OP_RRQ:
                STRCPY(filename, hdr->un.filename);
                STRCPY(mode,    (hdr->un.filename+STRLEN(filename)+1));
                set_tftpd_message(TFTP_OP_RRQ, 0, filename, mode, ip_hdr->saddr); /*lint !e613*/
                if(ip_connect!=0){
                    TimerStop(TimerTftpdTX);
                    timeout_wait_ack = 0;
                    tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ERR, 1, 
                                    "rrq is not expected!!!", 23);/*lint !e613*/
                    binary_mode = 0;
                    if(fp){
                        DispatchLock();
                        fclose(fp);
                        fp=NULL;
                        DispatchUnlock();
                    }
                    ip_connect = 0L;
                    break;
                }
                ip_connect = ip_hdr->saddr; /*lint !e613*/
                remote_port = INT16XCHG(u_hdr->source);
                if(mode[0]=='o'||mode[0]=='O'){ /* octet */
                    binary_mode = 1;
                } else {
                    binary_mode = 0;
                }
                DispatchLock();
                fp=fopen(filename, binary_mode?("rb"):("rt"));
                DispatchUnlock();
                if(!fp){
                    tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ERR, 2, 
                                    "file not found!!!", 18); /*lint !e613*/
                    ip_connect = 0L;
                    break;
                }
                DispatchLock();
                bytes=fread(buf, 1, 512, fp);
                DispatchUnlock();
                if(bytes!=512) last_blk = 1;
                else           last_blk = 0;
                blksn = 1;
                tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_DAT, 
                                 blksn, buf, bytes); /*lint !e613*/
                TimerReStart(TimerTftpdTX);
                timeout_resend = 0;
                break;
            case TFTP_OP_WRQ:
                STRCPY(filename, hdr->un.filename);
                STRCPY(mode,    (hdr->un.filename+STRLEN(filename)+1));
                set_tftpd_message(TFTP_OP_WRQ, 0, filename, mode, ip_hdr->saddr); /*lint !e613*/
                if(ip_connect!=0){
                    tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ERR, 1, 
                                    "wrq is not expected!!!", 23); /*lint !e613*/
                    binary_mode = 0;
                    if(fp){
                        DispatchLock();
                        fclose(fp);
                        fp=NULL;
                        DispatchUnlock();
                    }
                    ip_connect = 0L;
                    break;
                }
                ip_connect = ip_hdr->saddr;
                remote_port = INT16XCHG(u_hdr->source);
                if(mode[0]=='o'||mode[0]=='O'){ /* octet */
                    binary_mode = 1;
                } else {
                    binary_mode = 0;
                }
                DispatchLock(); 
                fp = fopen(filename, binary_mode?"wb":"wt");
                DispatchUnlock();
                if(!fp){
                    tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ERR, 2, "file can not write!!!", 22);
                    ip_connect = 0L;
                    break;
                }
                blksn = 0;
                last_blk = 0;
                blksn_old  = 0;
                tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ACK, blksn, NULL, 0);
                break;
            case TFTP_OP_DAT:
                set_tftpd_message(TFTP_OP_DAT, INT16XCHG(hdr->un.id), filename, mode, ip_hdr->saddr);
                blksn = INT16XCHG(hdr->un.id);
                if(blksn_old !=0 && blksn_old==blksn){
                    tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ACK, blksn, NULL, 0);
                    break;
                }
                if(blksn - blksn_old > 1){
                    tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ACK, blksn_old, NULL, 0);
                    break;
                }
                blksn_old=blksn;
                if(!fp || ip_connect==0L){
                    tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ERR, 3, "file not open!!!", 17);
                    break;
                }
                bytes = tftp_len-4;
                DispatchLock();
                MEMCPY(wbuf, ((INT08S *)hdr+4), (INT16S)bytes);
                fwrite(wbuf, bytes, 1, fp);
                if(bytes!=512){
                    fclose(fp);
                    fp=NULL;
                    ip_connect=0L;
                    set_tftpd_message(TFTP_OP_XXX, 0, "=== receive end ===", 0, ip_hdr->saddr);                    
                }
                DispatchUnlock();
                tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ACK, blksn, NULL, 0);
                break;
            case TFTP_OP_ACK:
                timeout_resend = 0;
                set_tftpd_message(TFTP_OP_ACK, INT16XCHG(hdr->un.id), filename, mode, ip_hdr->saddr);
                if(!fp || ip_connect==0L){
                    tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_ERR, 3, "file not open!!!", 17);
                    TimerStop(TimerTftpdTX);
                    timeout_wait_ack = 0;
                    break;
                }
                if(last_blk){
                    TimerStop(TimerTftpdTX);
                    timeout_wait_ack = 0;
                    DispatchLock();
                    fclose(fp);
                    fp=NULL;
                    DispatchUnlock();
                    ip_connect = 0L;
                    set_tftpd_message(TFTP_OP_XXX, 0, "=== transmit end ===", 0, ip_hdr->saddr);                    
                    break;
                }
                blksn++;
                DispatchLock();
                bytes=fread(buf, 1, 512, fp);
                DispatchUnlock();
                if(bytes!=512) last_blk = 1;
                else           last_blk = 0;
                tftpd_xmit(ip_hdr->saddr, INT16XCHG(u_hdr->source), TFTP_OP_DAT, blksn, buf, bytes);
                TimerReStart(TimerTftpdTX);
                break;
            case TFTP_OP_ERR:
                TimerStop(TimerTftpdTX);
                timeout_wait_ack = 0;
                binary_mode = 0;
                if(fp){
                    DispatchLock();
                    fclose(fp);
                    fp=NULL;
                    DispatchUnlock();
                }
                ip_connect = 0L;
                set_tftpd_message(TFTP_OP_ERR, hdr->un.err.err, hdr->un.err.err_msg, NULL, ip_hdr->saddr);
                break;
            default:
                break;
        }
        
        if(ip_connect==0L){               /* 当前没有连接, 定时器应该关闭         */
            TimerStop(TimerTftpdRX);
        }
        
        i_will_take_a_nap:
        tftp_packet_lock = 0;
        if(tftp_packet_received==0){
            TaskSleep(1000L);
        }
        
    }while(1);/*lint !e506 */

}
예제 #21
0
파일: tftpd.c 프로젝트: wsj-zz/FamesOS
void apical set_tftpd_message(INT16U opcode, INT16U blkid, 
                              INT08S *filename, 
                              INT08S *mode, 
                              INT32U src_ip)
{
    INT08S   ip_str[20];
    INT08S   t_mode[32] = "<NULL>";
    INT08S   t_flnm[128]= "<NULL>";

    if(tftpd_message.number >= TFTP_MESSAGE_BUF_NUM){
        tftpd_message.lost++;
        return;
    }

    ip_string(ip_str, src_ip);

    if(filename)
        STRCPY(t_flnm, filename);
    if(mode)
        STRCPY(t_mode, mode);

    switch(opcode)
    {
        case TFTP_OP_RRQ:
            DispatchLock();
            sprintf(tftpd_message.buf[tftpd_message.in], 
                 "tftp message: rrq: %s(%s) from %s", t_flnm, t_mode, ip_str);
            tftpd_message.in++;
            tftpd_message.number++;
            tftpd_message.in%=TFTP_MESSAGE_BUF_NUM;
            DispatchUnlock();
            break;
        case TFTP_OP_WRQ:
            DispatchLock();
            sprintf(tftpd_message.buf[tftpd_message.in], 
                 "tftp message: wrq: %s(%s) from %s", t_flnm, t_mode, ip_str);
            tftpd_message.in++;
            tftpd_message.number++;
            tftpd_message.in%=TFTP_MESSAGE_BUF_NUM;
            DispatchUnlock();
            break;
        case TFTP_OP_DAT:
            DispatchLock();
            sprintf(tftpd_message.buf[tftpd_message.in], 
                 "tftp message: dat: %-6d", blkid);
            tftpd_message.in++;
            tftpd_message.number++;
            tftpd_message.in%=TFTP_MESSAGE_BUF_NUM;
            DispatchUnlock();
            break;
        case TFTP_OP_ACK:
            DispatchLock();
            sprintf(tftpd_message.buf[tftpd_message.in], 
                 "tftp message: ack: %-6d", blkid);
            tftpd_message.in++;
            tftpd_message.number++;
            tftpd_message.in%=TFTP_MESSAGE_BUF_NUM;
            DispatchUnlock();
            break;
        case TFTP_OP_ERR:
            DispatchLock();
            sprintf(tftpd_message.buf[tftpd_message.in], 
                 "tftp message: err: %s(%d) from %s", t_flnm, blkid, ip_str);
            tftpd_message.in++;
            tftpd_message.number++;
            tftpd_message.in%=TFTP_MESSAGE_BUF_NUM;
            DispatchUnlock();
            break;
        default:
            DispatchLock();
            sprintf(tftpd_message.buf[tftpd_message.in], 
                 "tftp message: %s from %s", t_flnm, ip_str);
            tftpd_message.in++;
            tftpd_message.number++;
            tftpd_message.in%=TFTP_MESSAGE_BUF_NUM;
            DispatchUnlock();
            break;
    }
}