<del id="dhfrq"></del>

    1. <tr id="dhfrq"></tr>
      成人午夜激情在线观看,国产精品一线天粉嫩av,99精品国产综合久久久久五月天 ,一卡2卡三卡4卡免费网站,国产高清在线男人的天堂,五月天国产成人AV免费观看,67194熟妇在线观看线路,成人无码潮喷在线观看
      現(xiàn)在位置:范文先生網(wǎng)>理工論文>計(jì)算機(jī)論文>用Windows終端仿真程序?qū)崿F(xiàn)微機(jī)遠(yuǎn)程文件傳送1

      用Windows終端仿真程序?qū)崿F(xiàn)微機(jī)遠(yuǎn)程文件傳送1

      時(shí)間:2023-02-20 22:50:47 計(jì)算機(jī)論文 我要投稿
      • 相關(guān)推薦

      用Windows終端仿真程序?qū)崿F(xiàn)微機(jī)遠(yuǎn)程文件傳送1

         有些硬盤(pán)防拷貝是通過(guò)對(duì)硬盤(pán)FAT表中的簇鏈的檢測(cè)來(lái)實(shí)現(xiàn)的,這與本文所推薦的方法原理一樣,都是通過(guò)檢測(cè)文件位置信息是否被改變來(lái)判斷文件是否已被移動(dòng)的。但前者涉及到定位FAT表及文件所在目錄等繁瑣工作,而且還和硬盤(pán)型號(hào)及格式化信息有關(guān),編程很不方便。本文所介紹的方法則不然,它直接與操作系統(tǒng)打交道,取出操作系統(tǒng)內(nèi)核中現(xiàn)成的數(shù)據(jù),即利用DOS系統(tǒng)文件表(SYSTEM FILE TABLE 簡(jiǎn)稱(chēng)SFT)來(lái)實(shí)現(xiàn)防拷貝。
      當(dāng)您打開(kāi)硬盤(pán)上的一個(gè)文件并移動(dòng)讀寫(xiě)指針時(shí),DOS會(huì)時(shí)刻記錄讀寫(xiě)指針?biāo)鶎?duì)應(yīng)的硬盤(pán)位置。一個(gè)稍大些的文件在硬盤(pán)上要占用多個(gè)簇,這些簇并不是連續(xù)的,而是由操作系統(tǒng)一般按照“就近循環(huán)分配”原則為該文件分配的,這些簇的絕對(duì)簇號(hào)具有一定的隨機(jī)性,在FAT表中形成一個(gè)簇鏈。移動(dòng)讀寫(xiě)指針超過(guò)一個(gè)簇的大小時(shí),則所對(duì)應(yīng)的絕對(duì)簇號(hào)也要變化。只要該文件沒(méi)有被移動(dòng)過(guò)(拷貝或整理硬盤(pán)),這些簇號(hào)就是固定的。一旦該文件被移動(dòng)了,根據(jù)DOS簇分配原則,這些對(duì)應(yīng)的簇號(hào)就會(huì)改變。由此,我們可以檢查特定的文件指針?biāo)鶎?duì)應(yīng)的絕對(duì)簇號(hào)是否改變了來(lái)判斷該文件是否已被非法移動(dòng)。
      SFT是DOS在文件管理上的一個(gè)很重要的數(shù)據(jù)結(jié)構(gòu)。只要DOS開(kāi)始引用一個(gè)文件或設(shè)備,它必然要建立一個(gè)SFT。該表記錄了文件設(shè)備名、目錄特性、設(shè)備特性、文件大小和位置、DDPB(塊設(shè)備)或設(shè)備驅(qū)動(dòng)程序標(biāo)題(字符設(shè)備)的地址,以及打開(kāi)模式等有關(guān)文件的存儲(chǔ)、訪問(wèn)和操作的管理信息。其中有幾項(xiàng)數(shù)據(jù)可以用來(lái)確定文件在硬盤(pán)上的位置,它們是:文件讀寫(xiě)指針?biāo)鶎?duì)應(yīng)的絕對(duì)簇號(hào),目錄項(xiàng)的相對(duì)索引號(hào)(即目錄項(xiàng)在目錄扇區(qū)中的序號(hào)),目錄項(xiàng)所在扇區(qū)的扇區(qū)號(hào)。
      那么怎樣利用這幾項(xiàng)數(shù)據(jù)防拷貝呢?這里所說(shuō)的防拷貝是指可以拷貝但拷貝后的文件不能執(zhí)行或不能被使用,包括數(shù)據(jù)文件和可執(zhí)行文件。若是可執(zhí)行文件,則其本身包括一段檢測(cè)代碼,用以判斷其本身是否已被非法移動(dòng)。若是數(shù)據(jù)文件,則在使用該數(shù)據(jù)文件的可執(zhí)行文件中包括一段檢測(cè)代碼,來(lái)判斷該數(shù)據(jù)文件是否已被非法移動(dòng)。當(dāng)?shù)谝淮螌⒁粋(gè)文件裝入硬盤(pán)后,它所占有的硬盤(pán)的簇號(hào)已是固定的了。這樣我們就可以作一個(gè)加密程序,在該程序里,約定一個(gè)或多個(gè)秘密的值N,N1,N2…,然后將文件指針?lè)謩e移動(dòng)到N或N1,N2…,在SFT中取出那幾項(xiàng)硬盤(pán)位置數(shù)據(jù),再用約定的秘密算法加以運(yùn)算,就得到了包含被加密文件位置信息的“鑰匙”,將它存于另一個(gè)文件中或干脆附加在被加密文件的末尾。在使用該文件的可執(zhí)行文件的檢測(cè)代碼中,按同樣的算法取得當(dāng)前的“鑰匙”,與先前保存的“鑰匙”相比較,若相等,則說(shuō)明文件沒(méi)有被移動(dòng)過(guò),程序正常執(zhí)行,否則,說(shuō)明文件已不在先前的位置了,即已被非法移動(dòng)過(guò)了,則程序異常執(zhí)行。
      我們先看看DOS系統(tǒng)中SFT的具體結(jié)構(gòu),系統(tǒng)有多個(gè)SFT,這個(gè)數(shù)目取決于CONFIG.SYS文件中的FILES=N的N值。在DOS4.0,5.0,6.0中,每個(gè)SFT的長(zhǎng)度是3BH。多個(gè)SFT形成SFT數(shù)組,并不是整個(gè)系統(tǒng)的所有SFT組成一個(gè)連續(xù)的大數(shù)組,而是可能有多個(gè)SFT數(shù)組,每個(gè)數(shù)組由一個(gè)控制塊管理,它們之間由指針連接。每個(gè)SFT數(shù)組的結(jié)構(gòu)如下:
      偏移量 長(zhǎng)度 說(shuō)明
      00H DWORD 指向下一個(gè)SFT數(shù)組的指針
      04H WORD 本SFT數(shù)組內(nèi)的SFT數(shù)目
      06H nBYTEs 由SFT組成的數(shù)組(n=本數(shù)組中SFT數(shù)目*每個(gè)SFT所占字節(jié)數(shù))
      我們還必須知道第一個(gè)SFT數(shù)組所在的地址。這可由DOS功能調(diào)用52H先取得DOS的多重表指針,在多重表偏移量04H處即是一個(gè)長(zhǎng)指針,它即指向第一個(gè)SFT數(shù)組的頭部。這樣剩下的SFT數(shù)組的位置也就知道了。
      每當(dāng)DOS打開(kāi)一個(gè)新文件時(shí),DOS就從這些SFT數(shù)組中找一個(gè)空閑的SFT項(xiàng),分配給該文件。以后DOS就用此SFT控制訪問(wèn)該文件。那么怎樣確定一個(gè)剛打開(kāi)的文件所對(duì)應(yīng)的SFT項(xiàng)是SFT數(shù)組中的第幾項(xiàng)呢?我們利用文件句柄和文件句柄表。每個(gè)進(jìn)程都有一個(gè)文件句柄表,當(dāng)我們打開(kāi)一個(gè)文件時(shí)可得到該文件的句柄,它是一個(gè)整數(shù),設(shè)為M,則在文件句柄表中的第M項(xiàng)即為該文件的SFT表項(xiàng)在SFT數(shù)組中的位置。
      那么怎樣找到文件句柄表呢?我們先用DOS功能調(diào)用51H得到程序段前綴(PSP)的地址,在PSP偏移34H處即是指向該進(jìn)程文件句柄表的雙字指針。
      附圖給出怎樣找一個(gè)已打開(kāi)文件的SFT。
      @@02A08500.GIF;附圖@@
      打開(kāi)文件取得文件句柄是3,所對(duì)應(yīng)的SFT的序號(hào)是6。
      下面就給出一個(gè)可執(zhí)行文件防拷貝的例子。
      假設(shè)我們用C++語(yǔ)言編一個(gè)完成某一功能的程序NO-COPY.CPP,經(jīng)過(guò)編譯連接生成可執(zhí)行文件NO-COPY.EXE,要對(duì)這個(gè)可執(zhí)行文件實(shí)行硬盤(pán)防拷貝。我們先編寫(xiě)一個(gè)設(shè)置“鑰匙”的程序PUT-KEY,在該程序中按上述方法取得NO-COPY.EXE的“原鑰匙”(它包含了NO-COPY.EXE初次裝入硬盤(pán)時(shí)的位置信息),存于一個(gè)專(zhuān)用文件LOC-KEY.DAT中(當(dāng)然也可直接附加在NO-COPY.EXE的末尾,取時(shí)也到文件末尾去取),在NO-COPY.EXE中必須包含一段檢測(cè)代碼。
      它也用PUT-KEY的方法取出自己的“當(dāng)前鑰匙”,與存于LOC-KEY.DAT中的“原鑰匙”比較,相等則說(shuō)明文件還在原處,正常執(zhí)行。否則,說(shuō)明正在執(zhí)行的NO-COPY.EXE是被拷貝的副本,停止執(zhí)行或異常執(zhí)行。
      這里,不用考慮“鑰匙”的安全性,“鑰匙”是可以公開(kāi)的,只要取得“鑰匙”的方法是保密的,非法拷貝者就無(wú)可奈何?梢赃@樣理解這個(gè)防拷貝方法:可執(zhí)行文件本身具有自鎖性,在它每拷貝到一個(gè)新地點(diǎn)時(shí)就按文件位置上了一把新鎖,當(dāng)它執(zhí)行時(shí),它到一個(gè)固定的地方去取“鑰匙”,打開(kāi)本身的鎖執(zhí)行。當(dāng)它被移動(dòng)后,可理解為鎖換了(因?yàn)槲恢米兞?。用“原鑰匙”打不開(kāi),所以“原鑰匙”是可以公開(kāi)的,PUT-KEY.EXE就是用來(lái)設(shè)置“原鑰匙”的。當(dāng)合法用戶想把NO-COPY.EXE拷貝到一個(gè)新地方,只需運(yùn)行一次PUT-KEY.EXE就可以使用新的NO-COPY.EXE了。所以PUT-KEY.EXE必須由合法用戶保管。
      先編寫(xiě)一個(gè)取“鑰匙”的子程序,放在MAKE-KEY.CPP文件中,在該子程序中,分別取目錄項(xiàng)的相對(duì)索引號(hào),目錄項(xiàng)所在扇區(qū)的扇區(qū)號(hào),文件指針?biāo)鶎?duì)應(yīng)的絕對(duì)簇號(hào)。采用相加的算法,形成“鑰匙”。這里只用了一個(gè)文件指針6000所對(duì)應(yīng)的簇號(hào),當(dāng)然可以使用多個(gè)文件指針,采用更復(fù)雜的算法,如相乘、相除、異或、相減等。所用的文件指針和所用的算法是保密的。而算出的“鑰匙”可以是公開(kāi)的。
      MAKE-KEY.CPP的內(nèi)容如下(本文件用來(lái)被包含在PUT-KEY.CPP和NO-COPY.CPP中)。
      /*本子程序用來(lái)取filename的"當(dāng)前鑰匙"*/
      unsigned long curentlocation-key(char filename)
      {
      unsigned long secc;
      int filehandle;
      int i,iii,jjj1,jjj2;
      unsigned char u-char=0;
      unsigne

      d int u-int=0;
      unsigned long u-long=0;
      unsigned int offst1,segmnt1,offst2,segmnt2;
      void psp-ptrr;
      unsigned char far ptrr1, ptrr2;
      FILE Stream;
      Stream=fopen(filename,"r+b");
      if(Stream==NULL)
      {cputs("open error");exit(1);}
      filehandle=fileno(Stream); //取文件句柄;
      fseek(Stream,6000,0); //將文件指針置于6000處;
      fread(&i,2,1,Stream); //讀一次,使DOS按此文件指針修正SFT;
      asm push es
      asm mov ah,51h
      asm int 21h //取程序段前綴(PSP)段地址;
      asm mov es,bx
      asm mov ax,word ptr es:[52] //偏移量34H為文件句柄表(FHT)地址;
      asm mov bx,ax
      axm mov ax,word ptr es:[54]
      asm mov es,ax
      asm add bx,filehandle //文件句柄表中偏移filehandle 處的一字節(jié);
      asm mov al,byte ptr es:[bx] //為該文件的SFT在SFT數(shù)組中的序號(hào);
      asm xor ah,ah
      asm pop es
      asm mov iii,ax //iii中存放文件的SFT在SFT數(shù)組中的序號(hào);
      asm push es
      asm mov ah,52h //取DOS多重表指針;
      asm int 21h //es為段地址,bx為偏移量;
      asm mov ax,word ptr es:[bx+4] //多重表中偏移04H為第一個(gè)SFT數(shù)組控制塊指針
      ;
      asm mov offst1,ax //offset1為第一個(gè)SFT數(shù)組控制塊偏移量;
      asm mov ax,word ptr es:[bx+6]
      asm mov segmnt1,ax//segment1為第一個(gè)SFT數(shù)組控制塊段地址;
      asm mov es,segmnt1
      asm mov bx,offst1
      asm mov ax,word ptr es:[bx]
      asm mov offst2,ax//offset2為第二個(gè)SFT數(shù)組控制塊偏移量;
      asm mov ax,word ptr es:[bx+2]
      asm mov segmnt2,ax //segment2為第二個(gè)SFT數(shù)組控制塊段地址;
      asm mov ax,word ptr es:[bx+4]
      asm mov jjj1,ax //jjj1中存放第一個(gè)SFT數(shù)組的項(xiàng)數(shù),一般為五
      asm mov es,segmnt2 //個(gè)(系統(tǒng)保留的五個(gè)常用文件的SFT);
      asm mov bx,offst2
      asm mov ax,word ptr es:[bx+4]
      asm mov jjj2,ax //jjj2中存放第二個(gè)SFT數(shù)組的項(xiàng)數(shù),它一般等于
      asm pop es //CONFIG.SYS中FILES=N的N值減去第一個(gè)SFT
      //數(shù)組中SFT項(xiàng)數(shù)jjj1;
      ptrr1=(unsigned char far *)MK-FP(segmnt1,offst1+6);
      //ptrr1指向第一個(gè)SFT數(shù)組中第一個(gè)SFT
      Ptrr2=(unsigned char far *)MK-FP(segmnt2,offst2+6);
      //ptrr2指向第二個(gè)SFT數(shù)組中第一個(gè)SFT
      if(iii<jjj1) //若該文件的SFT序號(hào)小于第一個(gè)SFT數(shù)組的項(xiàng)數(shù),則它的SFT
      { //一定在第一個(gè)SFT數(shù)組中;
      // for(i=0;i<0x3b;i++) //這兩行可用來(lái)顯示該文件的SFT;
      // printf(" %2x",ptrr1[iii*0x3b+i]); //在DOS4.0-6.0中共0x3b個(gè)字節(jié);
      asm push es
      asm push di
      asm les bx,ptrr1 //第0個(gè)SFT的地址;
      asm mov ax, iii
      asm mov cx,3bh
      asm mul cx
      asm mov di,ax //第iii個(gè)SFT的地址,即要找的本文件的SFT;
      asm mov ax, word ptr es:[bx+di+1bh] //SFT中偏移1bH處是目錄項(xiàng)所在扇區(qū)的
      asm mov word ptr u-long,ax //扇區(qū)號(hào),可用于定位文件,取出存于
      asm mov ax, word ptr es:[bx+di+1dh] //u-long中;
      asm mov word ptr u-long+2,ax
      asm mov al,byte ptr es:[bx+di+1fh] //偏移1fH處是目錄項(xiàng)的相對(duì)索引號(hào),即

      asm mov u-char,al //錄項(xiàng)在目錄扇區(qū)中的序號(hào),也可用于定位
      //文件的位置,取出存于u-char中;
      asm mov ax,word ptr es:[bx+di+35h]//SFT中偏移35H處是文件讀寫(xiě)指針對(duì)應(yīng)的
      asm mov u-int,ax//絕對(duì)簇號(hào)(2字節(jié)),取出存于u-int中;
      asm pop di
      asm pop es
      }
      else
      {
      iii-=jjj1; //第二個(gè)SFT數(shù)組中的SFT項(xiàng)和第一個(gè)SFT數(shù)組中的項(xiàng)是統(tǒng)一編號(hào)的;
      // for(i=0;i<0x3b;i++)
      // printf(" %2x",ptrr2[(iii)*0x3b+i]);
      asm push es
      asm push di
      asm les bx,ptrr2
      asm mov ax,iii
      asm mov cx,3bh
      asm mul cx
      asm mov di,ax
      asm mov ax,word ptr es:[bx+di+1bh]
      asm mov word ptr u-long,ax
      asm mov ax,word ptr es:[bx+di+1dh]
      asm mov word ptr u-long+2,ax
      asm mov al, byte ptr es:[bx+di+1fh]
      asm mov u-char,al
      asm mov ax,word ptr es:[bx+di+35h]
      asm mov u-int,ax
      asm

      pop di
      asm pop es
      }
      u-long+=u-int; //這里采用的秘密算法是相加;
      u-long+=u-char;
      fclose(Stream);
      retrun u-long;
      }
      下面就是設(shè)置“鑰匙”的PUT-KEY/CPP文件的內(nèi)容。
      #include <stdio.h>
      #include <process.h>
      #include <dos.h>
      #include <io.h>
      #include <conio.h>
      #include "make-key.cpp" //將取鑰匙子程序包函進(jìn)來(lái);
      void main(int argc,char * argv[]) //命令行上是待加密的文件名;
      {
      unsigned long key=0;
      FILE *stream;
      if (argc<2)
      {cputs("specify a file");exit(1);}
      key=curentlocation-key(argv[1]); //取出文件當(dāng)前“鑰匙”;
      stream=fopen("loc-key.dat","w+b"); //以寫(xiě)方式打開(kāi)“鑰匙”文件loc-key.da
      t;
      if(stream==NULL)
      {cputs("can't open file loc-key.dat");exit(1);}
      fwrite(&key,4,1,stream); //將當(dāng)前“鑰匙”(4字節(jié))寫(xiě)入文件;
      fclose(stream);
      }
      下面就是NO-COPY.CPP的內(nèi)容:
      #include <stdio.h>
      #include <stdlib.h>
      #include <conio.h>
      #include <dos.h>
      #include <io.h>
      #include <stddef.h>
      #include <process.h>
      #include "make-key.cpp" //將取鑰匙子程序包函進(jìn)來(lái);
      //該程序main()函數(shù)如下:
      int main()
      {
      //下面是一段檢測(cè)代碼,(可放在程序中必要的地方);
      unsigned long proto-key,curent-key;
      FILE*Stream;
      Stream=fopen ("loc-key.dat","rb");//以讀方式打開(kāi)“鑰匙”文件;
      if(Stream==NULL)//若因破壞而打不開(kāi)則退出;
      {cputs("loc-key.dat open error");exit(1);}
      fread(&proto-key,4,1,Stream);//取存放于文件中的“原鑰匙”(4字節(jié));
      fclose(Stream);
      curent-key=curentlocation-key("d.exe");//按同樣的方法取“當(dāng)前鑰匙”;
      if(curent-key!=proto-key)//比較“當(dāng)前鑰匙”和“原鑰匙”;
      {
      cputs("The file has been moved and is invalid!");exit(1);
      }
      //若不相等,說(shuō)明當(dāng)前的文件位置與裝入時(shí)的位置不同,//文件已經(jīng)被移動(dòng)過(guò),這里可異常執(zhí)行;
      cputs("The file is valid");//否則正常進(jìn)行,完成程序的功能;
      //以下是程序代碼;
      //...
      //...
      return 0;
      }//為了防跟蹤,當(dāng)打不開(kāi)“鑰匙”文件或發(fā)現(xiàn)文件已被移動(dòng)過(guò)時(shí),可不退出,而是
      //異常執(zhí)行;
      以上程序用Borlandc c++3.1編寫(xiě),使用時(shí),分別編譯連接PUT-KEY.CPP和NO-COPY.CP
      P形成PUT-KEY.EXE和NO-COPY.EXE。然后在DOS提示符下鍵入:
      NO-COPY
      就會(huì)得到loc-key.dat open error 的信息,程序退出,這是因?yàn)檫沒(méi)有運(yùn)行PUT-KEY來(lái)設(shè)置“鑰匙”。
      若先鍵入PUT-KEY NO-COPY.EXE 來(lái)為NO-COPY.EXE設(shè)置“鑰匙”
      再鍵入NO-COPY
      則得到The file is valid 說(shuō)明正常執(zhí)行。
      若將NO-COPY.EXE拷貝到其它目錄再執(zhí)行就會(huì)得到loc-key.dat open error 的信息,程序退出。
      若將loc-key.dat 一起拷貝到其它目錄再執(zhí)行
      則得到The file has been moved and is invalid!
      若先在新目錄運(yùn)行PUT-KEY NO-COPY.EXE 來(lái)為新的NO-COPY.EXE設(shè)置“鑰匙”
      再運(yùn)行新的NO-COPY
      則得到The file is valid 說(shuō)明正常執(zhí)行。
      若要對(duì)一個(gè)或多個(gè)數(shù)據(jù)文件加密,可對(duì)PUT-KEY.CPP稍加修改,再在使用這些數(shù)據(jù)文件的可執(zhí)行文件的原程序中加入檢測(cè)代碼即可。若要修改加密算法或調(diào)整“鑰匙”的取出方
      法,則只需修改curentlocation-key()函數(shù)。


      【用Windows終端仿真程序?qū)崿F(xiàn)微機(jī)遠(yuǎn)程文件傳送1】相關(guān)文章:

      用Windows終端仿真程序?qū)崿F(xiàn)微機(jī)遠(yuǎn)程文件傳送08-06

      FoxPro for Windows 遠(yuǎn)程撥號(hào)通訊功能的設(shè)計(jì)與實(shí)現(xiàn)08-06

      遠(yuǎn)程終端中通信控制卡的設(shè)計(jì)與實(shí)現(xiàn)08-06

      用Borland C++3.1實(shí)現(xiàn)外設(shè)與Windows應(yīng)用程序?qū)崟r(shí)通信08-06

      Windows CE中實(shí)現(xiàn)藍(lán)牙串口驅(qū)動(dòng)程序08-06

      用VB實(shí)現(xiàn)對(duì)庫(kù)文件的分割備份08-06

      用Protel99SE實(shí)現(xiàn)脈沖電路的仿真08-06

      車(chē)載GPS智能終端的設(shè)計(jì)與實(shí)現(xiàn)08-06

      用MSP430實(shí)現(xiàn)的嵌入式因特網(wǎng)終端設(shè)計(jì)08-06

      主站蜘蛛池模板: 国产区成人精品视频| 欧美日韩亚洲国产| 国产乱码精品一区二区麻豆| 日韩精品一区二区在线看| 亚洲人成网线在线播放VA| 亚洲精品麻豆一二三区| 99久久亚洲综合精品成人| 国产精品久久中文字幕| 欧美成人h精品网站| 高清国产亚洲精品自在久久| 久女女热精品视频在线观看| 亚洲中文字幕一区二区| 午夜精品福利一区二区三| 国产网友愉拍精品视频手机| 国产热A欧美热A在线视频| 亚洲人午夜射精精品日韩| 亚洲日本高清一区二区三区| 2018年亚洲欧美在线v| 在线精品国产中文字幕| 久久精品夜夜夜夜夜久久| 国产色悠悠视频在线观看| 亚洲精品毛片一区二区| 国产婷婷精品av在线| 熟女精品色一区二区三区| 免费大片黄国产在线观看| 一区二区三区日本久久九| 蜜臀av久久国产午夜| 久久婷婷大香萑太香蕉AV人| 亚洲www永久成人网站| A级毛片100部免费看| 综合在线 亚洲 成人 欧美| 美女无遮挡免费视频网站| 又大又硬又爽免费视频| 中文激情一区二区三区四区| 欧美午夜成人片在线观看| 国产一区二区av天堂热| 亚洲美免无码中文字幕在线| 国产成人无码AV片在线观看不卡| 2021国产精品视频网站| 永久免费无码av在线网站| 成人午夜福利精品一区二区 |