Social Icons

Pages

Featured Posts

2017年10月16日 星期一

[windows driver] 如何設定 windows 的數位簽章

最近要替 windows 7, 8, 8.1, 10 的 driver 設定數位簽章,以下針對不同版本的windows的數位簽章流程做個紀錄。

需要工具: Windows Driver Kit 裡面的 inf2cat, signTool 、makeCab(windows 內建工具)。

需要檔案: certification.cer , 這個檔案是要向微軟購買的數位簽章, 一個 token USB裡面的檔案.

Windows 7:
step1: 利用 inf2cat 建立 cat檔案 /driver: driver 的路徑
    /os: driver的平台 ( XP_X86,XP_X64,Vista_X86,Vista_X64,7_X86,7_X64)

  以 windows 7 64bit為例:
 inf2cat /driver:"d:\driver\" /os:7_X64


  step2:利用certification.cer 建立數位簽章

signtool sign /v /ac "C:\Sign\certification.cer" /s my /n "Company name" /t http://timestamp.verisign.com/scripts/timestamp.dll "d:\driver\catalog.cat"
signtool sign /v /ac "C:\Sign\certification.cer" /s my /n "Company name" /t http://timestamp.verisign.com/scripts/timestamp.dll "d:\driver\driver.sys"

Windows &8.1:
step1: 新增 echo.cdf 檔案來建立 cat檔案

 OSAttr:2:6.2-->windows8, OSAttr:2:6.3-->windows81,

 echo.cdf:
[CatalogHeader]
Name=nvme86.cat
PublicVersion=0x0000001
EncodingType=0x00010001
CATATTR1=0x10010001:OSAttr:2:6.3
[CatalogFiles]
<hash>File1=F:\nvmeDriver\windows81\x86\1.5\nvme.inf
<hash>File2=F:\nvmeDriver\windows81\x86\1.5\nvme.sy

 使用WinDDK工具makecat執行 makecat -v echo.cdf 做出nvme86.cat檔案(檔案會放在makecat程式的資料夾)

step2:利用certification.cer 建立數位簽章

signtool sign /v /ac "C:\Sign\certification.cer" /s my /n "Company name" /t http://timestamp.verisign.com/scripts/timestamp.dll "d:\driver\catalog.cat"
signtool sign /v /ac "C:\Sign\certification.cer" /s my /n "Company name" /t http://timestamp.verisign.com/scripts/timestamp.dll "d:\driver\driver.sys"

windows 10:
step1: 新增 echo.ddf 檔案來建立 cab檔案:
MakeCab /f "d:\driver\echo.ddf

echo.ddf:
.OPTION EXPLICIT ;Generate errors
.Set CabinetFileCountThreshold=0
.Set FolderFileCountThreshold=0
.Set FolderSizeThreshold=0
.Set MaxCabinetSize=0
.Set MaxDiskFileCount=0
.Set MaxDiskSize=0
.Set CompressionType=MSZIP
.Set Cabinet=on
.Set Compress=on
;Specify file name for new cab file
.Set CabinetNameTemplate=nvmex64.cab
;Specify the subdirectory for the files.  
;Your cab file should not have files at the root level, 
;and each driver package must be in a separate subfolder.
.Set DestinationDir=x64
;Specify files to be included in cab file
F:\nvmeDriver\windows10\x64\nvme.inf
F:\nvmeDriver\windows10\x64\nvme.sys

step2:利用certification.cer 建立數位簽章

signtool sign /v /ac "C:\Sign\certification.cer" /s my /n "Company name" /t http://timestamp.verisign.com/scripts/timestamp.dll "d:\driver\nvmex64.cab"

把各版本都做好數位簽章後,經過WHQL test完成後就可以透過此連結登入微軟的儀表板並由微軟來提供官方的數位簽章

2017年6月20日 星期二

Android SOAP client

這次的問題需要使用 soap 格式來和 WSDL server 連線傳遞資訊。因為 Android 沒有支援 soap 的 library 所以需要額外掛載支援 soap 的 Ksoap2 jar。
但是試過 Ksoap2 後發現它包出來的格式和WSDL的格式無法符合,讓server 無法解析。在<soapenv:Envelope>中無法自訂自己的namespace資訊。所以只能自己動手包出request,以下詳細說明各段所需程式碼。
基本所需的變數
private final String MAIN_REQUEST_URL = "http://tmpuri.org/";
private final String NAMESPACE = "http://namespaceuri.org/";
private String SOAP_ACTION = "http://namespaceurimethod.org/";
private HttpURLConnection SERVER_CONNECTION;

此request範例是我遇到的 WSDL server內定的格式,所以可能會跟別人遇到的有點誤差,自行調整
request範例
String requestString = "<Request>"+
    "<Access/>"+
    "<RequestContent>"+
    "<Parameter>"+
    "<Record>"+
    "<Field name=\"user\" value=\"hello\" />"+
    "<Field name=\"pwd\" value=\"abc1234\" />"+
    "</Record>"+
    "</Parameter>"+
    "<Document />"+
    "</RequestContent>"+
    "</Request>";
String actionName = "CheckLogin";

包出SOAP格式
public String getSoapEnvelope(String actionName, String requestString) {
    SOAP_ACTION += actionName;
    String soapEnvelope = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:sv=\""+NAMESPACE+"\">" +
               "<soapenv:Header/>" +
               "<soapenv:Body>";
    soapEnvelope += " <tip:"+actionName+"><sv:request>";
    //add request
    soapEnvelope += requestString;
    soapEnvelope += "</sv:request></sv:"+actionName+">";
    soapEnvelope += "</soapenv:Body></soapenv:Envelope>";
    return soapEnvelope;
}

包出soap envolope後,就可以把這個字串透過http request傳送給server
建立http request
public String sendRequestToSystem(String soapEnvelope) {
    BufferedReader rd = null;
    String line;
    String resultXML = "";
    try {
 //create connection
        URL url = new URL(MAIN_REQUEST_URL);
        HttpURLConnection soapServerConnection = (HttpURLConnection) url.openConnection();
        soapServerConnection.setDoOutput(true);
        soapServerConnection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
        soapServerConnection.setRequestProperty("SOAPAction", SOAP_ACTION);
        soapServerConnection.setRequestProperty("POST", MAIN_REQUEST_URL+" HTTP/1.1");
        soapServerConnection.setRequestProperty("Content-Length", "" + soapEnvelope.length());
        soapServerConnection.setRequestProperty("Accept-Encoding", "gzip,deflate");
        soapServerConnection.setRequestMethod("POST");
        byte[] postData = soapEnvelope.getBytes();
        //send data to soap server
        DataOutputStream wr = new DataOutputStream(this.soapServerConnection.getOutputStream());
        wr.write(postData);
        wr.close();
        //read data from soap server
        BufferedReader rd = new BufferedReader(new java.io.InputStreamReader(soapServerConnection.getInputStream()));
        while ((line = rd.readLine()) != null) {
     line = line.replace("&lt;", "<");
     line = line.replace("&gt;", ">");
     resultXML += line;
 }
    } catch (MalformedURLException e) {
 e.printStackTrace();
    } catch (ProtocolException e) {
 e.printStackTrace();
    } catch (IOException e) {
 e.printStackTrace();
    } catch (Exception e) {
 e.printStackTrace();
    }
    return resultXML;       
}

依照上述流程透過 resultXML變數就可以取得 soap response資訊
推薦一個測試WSDL的工具: SOAP UI
可以建立一個WSDL的project連線到server 測試每個request 很方便.

2017年4月14日 星期五

awk string parsing uses shell variables

I need to parse user input parameters in shell file, so I do some research for it..

1.shell parameter format:
VAR=$(expr.)


2. awk function to replace string:  gsub("target string","replace string")
   sed way:                                      sed 's/target string/replace string/g'

3. awk use shell parameters : -v
   str1="shell value"
   echo awk -v S_RN=${str1} '{ print S_RN}'

Through 1 to 3 steps, we can use parameters from user input in awk function. 
See below example:
command line:
./test.sh "-i $RN -c -a"

test.sh:
RN=$RANDOM

FLAG=$(echo $1| awk -v S_RN=${RN} '{gsub("\$RN",S_RN);print}')

2017年4月7日 星期五

Java UI 元件透明

因為要JtabbedPane 的每個tab panel空出一個區塊統一去顯示Log訊息,所以把JtabbedPane的背景設為透明,讓每個tab panel都空出一個預設區塊去顯示Log panel.



JPanel 透明語法:
JPanel  trPanel = new JPanel ();
trPanel.setBackground(null);
trPanel.setOpaque(false);

JTabbedPane 透明語法:
UIManager.put("TabbedPane.contentOpaque", false);
JTabbedPane trTabbePane = new JTabbedPane();

JFrame 設定背景顏色:
JFrame jf = JFrame();
jf.getContentPane().setBackground(Color.RED);

2016年9月6日 星期二

Oracle Linux 6.8 in USB loader

使用 unetbootin 或 Universal-USB-Installer 都可以把 Oracle Linux 6.8的iso檔案燒入到USB。但是在安裝過程時會出現

Missing ISO 9660 Image

The installer has tried to mount image #1, but cannot find it on the hard drive.
Please copy this image to the drive and click Retry.
Click Exit to abort the installation.


解決辦法:
在使用上述工具把檔案寫入到USB完成後,要再把.iso檔案放到USB的root folder(就是直接放到USB裡面不用放到任何資料夾中)。
如此重新安裝後就可以順利完成。

2015年9月23日 星期三

[android] record video

        在專案中要使用 android 的 camera 來實作錄影與拍照功能. 雖然網路上有許多範例但是還是會遇到一些問題.

以下是使用Camera 必備的 Activity 架構
public class MainActivity extends Activity implements SurfaceHolder.Callback{

    private SurfaceView surfaceview;
    private MediaRecorder mediarecorder;
    private SurfaceHolder surfaceHolder;
    private Button startButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ...
    }

    @Override
    protected void onResume(){
        camera = Camera.open();
        if (phoneConfigure.orientation == Configuration.ORIENTATION_PORTRAIT)
            camera.setDisplayOrientation(90);
        super.onResume();
    }
 
    @Override
    protected void onPause(){
        camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
        super.onPause();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // TODO Auto-generated method stub
       Camera.Parameters parameters = camera.getParameters();
       parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); 
  
       camera.setParameters(parameters);
       camera.startPreview();
    }
 
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
 
      // TODO Auto-generated method stub
      try {
  
          camera.setPreviewDisplay(surfaceHolder);
   
      } catch (IOException e) {
          // TODO Auto-generated catch block
          camera.release();
          camera = null;
          e.printStackTrace();
      }
    }
 
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
         // TODO Auto-generated method stub 
 
    }  

  
}

下面是錄影的相關重要程式碼

 public void startRecord(int videoWidth,int videoHeight){
 
 mediarecorder = new MediaRecorder();
  
 camera.stopPreview();  
 camera.unlock();
 mediarecorder.setCamera(camera);
 mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
 mediarecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
 mediarecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
 mediarecorder.setVideoSize(videoWidth,videoHeight);
 if (phoneConfigure.orientation == Configuration.ORIENTATION_PORTRAIT)
     mediarecorder.setOrientationHint(90);
 mediarecorder.setOutputFile(createVideoFilePath(fileExtention));
 mediarecorder.setPreviewDisplay(surfaceHolder.getSurface());
  
 try {
     mediarecorder.prepare();
     mediarecorder.start(); 
 }catch (Exception e) {
     mediarecorder.stop();
     mediarecorder.release();
     e.printStackTrace();
     toast(e.getCause().toString());
 }
 }

 public void stopRecord(){
     if (mediarecorder != null) {
         mediarecorder.stop();
         mediarecorder.release();
         mediarecorder = null;
     }
 }
完整相關程式碼: Github

2015年9月8日 星期二

[android] external sdcard path 取得

 20171215:更新多種其他android手機SD path路徑方式
在 android 4.4版本之後 無法任意存取sd card的位置, 只能寫入與存取自己app 下的資料夾
 /Android/Data/<app-packagename>/
  ex: (/Android/Data/com.example.myapp/)

先利用 getExternalFilesDir(null);
可以自動在內部儲存空間和SD card創立 /Android/Data/<app-packagename>/ 資料夾

因為每個手機的sdcard 路徑都會不同
利用 System.getenv("SECONDARY_STORAGE"); 來取得sd card 的路徑 (ex, /storage/sdcard1/) 最後sdcard的路徑就可以寫成
getExternalFilesDir(null);
String path = System.getenv("SECONDARY_STORAGE") + "/Android/Data/com.example.myapp/";
android 6.0 SD card path
 private String androidMarshmallowSDcardPath() {
  String rootPath = null;
  File f = new File("/storage");
  if (f.isDirectory()) {
   String[] s = f.list();
   for (int i = 0; i < s.length; i++) {
    if(s[i].matches(".*-+.*")) {
     rootPath ="/storage/" + s[i];
     break;
    }else if(s[i].matches("exfat_uuid")) {// SONY Z3 SD card path name
     rootPath ="/storage/" + s[i];
     break;
    }
   }
  }
  return rootPath;
 }
如果把SD card 格式化成內部儲存空間,例如 HTC M8手機以上有支援此功能
SDcardPath = "/storage/emulated/0/Android/data/com.example.myapp/";
//SONY Xperia Miro
if(android.os.Build.MODEL.matches(".*ST23a+.*")) {
     SDcardPath = "/mnt/ext_card" +"/Android/data/com.phison.sdcardtest/";
}
相關permission
<uses-permission android:name="android.permissions.WRITE_EXTERNAL_STORAGE" />
 
 
Blogger Templates