2013年2月28日木曜日

Arch LinuxをVirtualBoxにインストールしてみた。

Arch Linux(64 bit)をVirtualBoxの仮想HDDにインストールしてみた。
手間取るかとおもったが一発でうまくいった。
我ながらLinuxになれてきたとかんがえたらいいのか?
以下はその手順。

インストールガイドでやってもいいのだと思うが
ビギナーズガイドでうまくいきました
VirtualBox guest additionのドライバもうまく入ったよ。
情報元は以下の4か所
https://wiki.archlinux.org/index.php/Beginners%27_Guide
https://wiki.archlinux.org/index.php/VirtualBox#Install_the_Guest_Additions
https://wiki.archlinux.org/index.php/GNOME
https://wiki.archlinux.org/index.php/GDM

手順をざっくり書きます
①ブートCDを用意します
http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/iso/2013.02.01/archlinux-2013.02.01-dual.iso
たとえばこれです
https://www.archlinux.org/download/
ここにあります

②仮想マシンを用意
   私は常に80G用意しているので今回もそれ
   メモリは5Gにした
   CPUは2コア
   UTCはON

③仮想マシンを①のCDから起動
  
④まずshellが起動するので
# loadkeys jp106
で日本語キーボードにする

⑤ネットがつながるのをpingで確認

⑥仮想ディスクのパーティションを切る
  1G SWAP (/dev/sda1)
  残り EXT4 (/dev/sda2)とした。
              /dev/sda2 はブートフラグ付き

⑦HDDをマウント
# mount /dev/sda2 /mnt
# mkdir /mnt/home 


⑧pacmanのミラーリスト(/etc/pacman.d/mirrorlist)を編集
日本を先頭に持ってくる
# pacman -Syy
が動作するのを確認

# pacstrap -i /mnt base base-devel
# pacman-key --init && pacman-key --populate archlinux 
# genfstab -U -p /mnt >> /mnt/etc/fstab
# nano /mnt/etc/fstab
       で問題ないのを確認
# arch-chroot /mnt
# nano /etc/locale.gen
  ここで
  en_US.UTF-8 UTF-8
  ja_JP.UTF-8 UTF-8 
       だけ先頭の#をとる
# locale-gen
# echo LANG=ja_JP.UTF-8 > /etc/locale.conf 
# export LANG=ja_JP.UTF-8
# loadkeys jp106
# setfont Lat2-Terminus16 
# nano /etc/vconsole.conf
  で以下の記述 
  KEYMAP=jp106
  FONT=Lat2-Terminus16 
# pacman -S ttf-sazanami 
# ln -s /usr/share/zoneinfo/Japan /etc/localtime 
# hwclock --systohc --utc
# echo myhostname > /etc/hostname 
# systemctl enable dhcpd.service
# systemctl start dhcpcd
# pacman -S ifplugd
# mkinitcpio -p linux
# passwd
# useradd -m -g users -G wheel -s /bin/bash ログイン名
# passwd ログイン名
# pacman -S grub-bios
# grub-install --target=i386-pc --recheck /dev/sda
# cp /usr/share/locale/en@quot/LC_MESSAGES/grub.mo /boot/grub/locale/en.mo
# grub-mkconfig -o /boot/grub/grub.cfg
# exit
# umount /mnt
# reboot
Rebootと書いてあるが実際はCDを取り外して(③のisoをvirtualboxから外して)再起動
うまくいけばログインコンソールが出るはず。 
ログインできるのを確認
 rootでログインかsuでrootになった後で
# pacman -S xorg-server xorg-xinit xorg-server-utils
# pacman -S mesa
# pacman -S virtualbox-guest-utils
# modprobe -a vboxguest vboxsf vboxvideo
# nano /etc/modules-load.d/virtualbox.conf で
  vboxguest
  vboxsf
  vboxvideo  
     を記述 
ここで再起動してlsmodで今書いた 
vboxguest vboxsf vboxvideo
がモジュールにあるのを確認
 
# pacman -S xorg-twm xorg-xclock xterm
ここでrootから普段使用するアカウントに変える。
$ rm ~/.xinitrc
$ startx
 見事Xが立ちあがって xterm xclock がでればOK 

ここからはxtermの作業 
# pacman -S gnome
# pacman -S gnome-extra
# pacman -S gdm
# systemctl enable gdm.service 
ここで再起動すればgdmが自動起動して
GUIでログインできるはず
そしてgnomeが立ち上がるはずです.
 

パーティション分けとネット接続で手間取るかも知れないがあとは簡単です
今回思ったのはUEFI対策がこまごまと書いてあって超ウザいこと
Windows8ではやるべきでないな。 
  

  

2012年11月25日日曜日

リモートデスクトップ:x2go

ubuntuを12.10にしてみました。
これを機会にバックアップして新規にインストールしなおしました。
なかなかいい感じですよ。

でちょっと困ることはfreenxがubuntu 12.10で使えなくなってた。
んでかわりにx2goを入れてみた。
http://www.x2go.org/
これもfreenxと同じ感覚で使える便利ソフトだ。
インストールするには
サーバーは
$ sudo add-apt-repository ppa:x2go/stable
$ sudo apt-get update
$ sudo apt-get install x2goserver x2goserver-xsession
で入れられます
 
 私の場合クライアントがWindowsなのでクライアントは
http://code.x2go.org/releases/binary-win32/x2goclient/
から
http://code.x2go.org/releases/binary-win32/x2goclient/x2goclient-3.99.0.0-setup.exe
を入れました。
下の絵はちょっと小さいサイズですがフルサイズにもできますよ。
あと音が出ないという問題は残っているがあとで考えます。
 

ついでに現状のubuntu 12.10 quantal で使用可能なリモートデスクトップサーバーをまとめてみる
vnc
vino
xrdp
teamviewer
x2go
ぐらいか?
このうち最初の3個は遅いのであまり好きではない 。
でteamviewerとx2goの2択だが私としてはx2goがお勧めだと思う


2012年11月18日日曜日

ubuntuではできないこと

今回はubuntuでは出来ないこと(というか私が解決できないこと)についてまとめてかいておきたい

1、地デジをみること。
 これ、まったく方法がないわけではなく
   PT2などの特殊な基板or USBワンセグ機器を使う
   USBにワンセグ機器を挿してVirtualboxとかのWindowsから見る
   keyholetvで他人の放送しているものをみる
 かのどれかになる。
 ”PT2などの特殊な基板を使う”で行きたいところですが、
   いまのところkeyholetvで満足です。TV自体見なくなったので。
 
  PT2:http://desktoplinuxhowto.blogspot.jp/2012/04/ubuntu-1204-lts-pt21110.html
   ワンセグでTVをみる:http://www2.it-ishin.com/archives/2011/11/861
   KeyHoleTV:http://www.v2p.jp/video/

2.DRM(デジタル著作権管理)関係の処理
 これについてもその場しのぎの処理しかubuntuではありません。
 Silverlight関係はMoonlightができたのですが
 これはDRM関係のものは再生できない(だからGyaoとかが基本だめ)
 あとiTune storeから買ったものを聞くこともできない。
 ただときどきbansheeとかにiTune連携ソフトが付いていることがある。
 Gyaoをubuntuで見る方法はこの前かいたんでそれを見てください。
 
   Moonlight:http://www.go-mono.com/moonlight/
   GyaoをUbuntuで見る: http://kokawa2003.blogspot.jp/2012/02/ubuntugyao.html

3.Internet Explorerに特化したサイトをみる
 IE自体はIE4Linuxなどを使えば入れられるがあまりしたくない処理だ
 あとActive Xなどがあったけどこれはもうほとんど問題にならないぐらい
 つかわれなくなった。でもいまだに役所のサイトとかを仕事でみてると
 引っかかるときがたまにある。で Active Xをインストールしてくださいとか
 いまだに言われたりする。
 
   IE4Linux:http://www.tatanka.com.br/ies4linux/page/Main_Page

4.プリンターとか無線LANとか使えないことがある。
 これについてはドライバーがあるかどうかって話だけど
 古いプリンターだとないことが多いような気がする。
 でも無線LANはUSBのやつでなければたぶん行ける。
     
こんなあたりができないことの代表だと思う。
 

2012年10月14日日曜日

Linuxとセキュリテイ

今回はlinuxとセキュリテイの話をしたい。

まずセキュリテイと言えばアンチウイルスの話なのだが、この件については必ず
”Linuxではアンチウイルスソフトは入れる必要ありません。なぜなら実行権がとれないしルートになれないから"
的な説明があると思う。じゃLinuxで動くウイルスはないのか?ってことになるが、
これはたとえばまとめサイトLinuxにおけるマルウェア によると2006年(ちょっと古い)の時点で、853件あるらしい。つまりあるってことはウイルスにかかる可能性があるってことになる。が853個ぐらいどうでもいいという考えも同時に成り立つ。これらはサーバーの設定が甘くて外部からスクリプトが動かせるとかのものだ。この853件が耐えられないと思う人はアンチウイルスソフト入れるといいと思うが私自身は無視してかまわないと思う。パスワードがばれなけば100%システム壊れないし悪さしてもホームのアクセス可のファイルを書き換えるだけだしね。
だがlinuxをサーバーとしている場合、自身は感染しなくてもウイルスを中継する可能性がある。これが本当の意味での脅威だ。警察が突然訪れてウイルスメール発信していますって感じで誤認逮捕されるかもしれないわけだから。メール発信はスクリプトが動作すればルート権なしで出来るからちょっと甘い設定だとやられるかも知れない。
とりあえずubuntuならclamtk(ClamAV)がapt-getから入れられます。Linux用のフリーのアンチウイルスソフトをまとめると
ClamAV   
avast! Linux Home Edition                                    
avg              
Avira Free Antivirus                           
Bitdefender
f-prot 
などがあるみたいだ。 あと有料のものも当然あるが、うざいので書かない。ただはっきりいえることは、業務でサーバーを作ったことは何回かあるが、アンチウイルスが話題になったことはいちどもないってことです。

次のセキュリテイの話としてはファイヤーウォールufwの話だろう。
これでどのポートを開けてどのポートを閉めるか決められます。
常識なのでこれ以上書かない。GUIが欲しい人はgufwを使ってください。
ubuntuならapt-getで入れられます。

次のありがちな話としてブルートフォース攻撃に対処ってのがあります。
自宅のマシンをサーバにしているとき、この攻撃を受けることはよくありますんで対策してます。それは普通DenyHostsで対策するようです。設定はこことかよんでください。
またSSHサーバなら
/etc/ssh/sshd_configに
MaxStartups 2:80:5 
とか書いてアクセス制限する方法もあります。

次のセキュリテイの話としてルートキットの話をしたい。
詳しい説明はリンク先を読んでもらうとして、結論からいって自宅のマシンがsshサーバーなのでこれは非常に怖い。自宅マシンが乗っ取られてしまうわけだから。でボットとか仕込まれる可能性がある。なのでこの問題には私もさすがに対処しててrkhunterを使ってます。インストールはubuntuなら
sudo apt-get install rkhunter
使い方はこんな感じです。


最後の話としては/etc/hostsに細工してやばいサーバーを元からブロックするってのがあります。この手の話でよくあるのが広告をブロック(アドブロック)しようってこと。
要するに、/etc/hosts に  "127.0.0.1 www.やばいURL.jp" のエントリを追加すれば
そのURLにアクセスできなくなるからブラウザーで広告ブロックとかに使えるってこと。
でそのやばいURLのリストはいろいろ出回っている
http://www.mvps.org/winhelp2002/hosts.txt
http://www.mvps.org/winhelp2002/hosts.zip
http://hostsfile.mine.nu/Hosts.zip
http://hostsfile.mine.nu.nyud.net:8080/
http://someonewhocares.org/hosts/hosts
http://www.malwarepatrol.net/cgi/submit?action=list_hosts_win_127001
http://www.malwaredomainlist.com/hostslist/hosts.txt
http://www.possessionstudios.com/hosts.txt
http://blocksites.webs.com/hosts_linux.zip
http://lineage.paix.jp/guide/security/hosts.txt
http://sky.geocities.jp/ro_hp_add/ro_hp_add_hosts.txt
http://jamesisbored.com/iphone/content/hosts
http://pgl.yoyo.org/as/serverlist.php?showintro=0;hostformat=hosts;mimetype=plaintext
http://www.hostsfile.org/Downloads/hosts.txt
http://www.securemecca.com/Downloads/hosts.txt
http://hostsfile.org/Downloads/hosts.txt
http://support.it-mate.co.uk/downloads/HOSTS.txt
http://www.montanamenagerie.org/hostsfile/hosts.txt
http://hosts-file.malwareteks.com/hosts.txt
http://temerc.com/hphosts/hosts.txt
http://avant.it-mate.co.uk/dl/Tools/hpHosts/HOSTS.txt
http://www.calendarofupdates.com/updates/hosts.txt
http://hphosts.gt500.org/hosts.txt
http://downloads.securitycadets.com/hphosts.zip
http://archives.mysteryfcm.co.uk/security/network/hosts_file/hphosts/hosts.txt
以下はサイト
http://www.freewebs.com/blocksites/
http://www.hosts-file.net/
http://remember.mine.nu/
http://winhelp2002.mvps.org/hosts.htm
https://gist.github.com/1031407
http://www.mdgx.com/hosts.php
http://www.mwsl.org.cn/?page_id=12
http://iphonech.com/archives/52583217.html
ここではスクリプトがある
http://hostsfile.mine.nu/downloads/updatehosts.sh.txt
http://bodhizazen.net/Tutorials/adblock
組み合わせて使って欲しい。

いろいろ書いたが結論としてはパスワード管理とサーバでスクリプトが動作しないようにチェックしとけってことで。それがしっかりしていればまずハックされないと考えていいと思う。パスワードがばれた場合ボットなどを仕込まれて最悪再インストールするしかなくなる可能性があり、またサーバでスクリプトが勝手に動けば最悪、警察に逮捕される可能性があります。

2012年10月5日金曜日

UBUNTUの64ビットについて

ubuntuの64bitについてインストールする方法を述べたい。
まずそもそも入手元ホームページは
http://www.ubuntulinux.jp
http://www.ubuntu.com
のどちらか(ミラーサイトなどは除く)なのだが、このhttp://www.ubuntulinux.jp には32bitのイメージしか現在ない。
よって64bitのUbuntuを使うにはhttp://www.ubuntu.com からインストールするしかないが、そうするとJapanese teamのリポジトリが入らないという悩ましい状況に陥ってしまう。これを避けるためにはリポジトリを手動でインストールすればよい。
つまり、
http://www.ubuntu.com/download/desktop から64ビットをダウンロードしてインストール後
http://www.ubuntulinux.jp/japanese#repository の通りにリポジトリを追加すればいい。
具体的にはUbuntu 12.04 LTSの場合:
wget -q https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg -O- | sudo apt-key add -
wget -q https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg -O- | sudo apt-key add -
sudo wget https://www.ubuntulinux.jp/sources.list.d/precise.list -O /etc/apt/sources.list.d/ubuntu-ja.list
sudo apt-get update
sudo apt-get upgrade
画面右上の「電源」アイコンをクリックし、[システムの設定]を開きます。「フィルタ」に
“言語サポート”と入力して、[言語サポート]画面を開きます。
「メニューとウインドウの言語」として日本語が含まれていることを確認します。
含まれていなければ、[言語のインストールと削除]から日本語を選択し、言語設定を
追加します。
sudo apt-get install ubuntu-defaults-ja
   
と操作することをさす。
これで64bitでもJapanese Remix CDとほぼ同じ環境になります。
今の私のマシンはこうして作りました。


2012年9月30日日曜日

C言語でシリアル通信



ANDROID,LINUX,WINDOWS,MAC
それぞれの環境でUSBシリアル通信(組み込み的にはUART通信)のプログラムを
つくったのでその感想を述べたい。

まず、androidだが、これはLINUXの一部なのだが、ドライバがほとんど対応してない。だからLINUXで/dev/ttyUSBのファイルができるのを確認しているドングル、ケーブルなどをUSBミニとUSBとの変換器経由で接続しても、ほとんど/dev/ttyUSBのファイルができない。これはUSBの変換器の不具合ではなく、androidのカーネルにドライバがないため。これをクリアするためにカーネルのフラグを立ててビルドしなおしてもだめ。理由はandroid appからアクセスするときアクセス権で拒否られるため。結局カーネル、シェル両方書き換えてOSごとインストールする必要あり。それでデバイスファイルができアクセス権も取れ、アプリからアクセス可能となる。

このあたりの顛末は
”google nexusにandroidを再インストール”
でかきましたんで興味がある人は読んで

 ただBluetooth用のUARTのチップを使った装置との通信なら上のようなことをする必要ないらしい。(したことないので分からないが)

次LINUX
一番素直なシリアル通信コードがかける。さすがC言語オリジナルという感じ
QTでコーデイングすればそのままMACでも同じコーデイングが使用可能。上の処理をすればそのままandroidでも動作する。

やり方。まずケーブル、ドングルなどシリアル通信するハードを接続。
ここで /dev/ttyUSB? というファイルが出来るのを確認。
何もほかに差してないなら、/dev/ttyUSB0 です。たぶん。

でC言語コーディングの話に移ります。
QTで私は作成しましたがなんでも同じです。
①ポートオープン

# include <stdio.h>
# include <stdlib.h>
# include <termio.h>
# include <unistd.h>
# include <fcntl.h>
# include <getopt.h>
# include <time.h>
# include <errno.h>
# include <string.h>
#include <sys/time.h>
 #include <unistd.h>

    struct termios TtyAttr;

    int DeviceSpeed = B9600;
    int ByteBits = CS8;
    char DeviceName[32];//="/dev/ttyUSB0";
    fd_set ReadSetFD;

int ncommFd=open(DeviceName, O_RDWR, 0);
    if (fcntl(ncommFd F_SETFL, O_NONBLOCK) < 0)
    {
            Error("Unable set to NONBLOCK mode");
            return ERROR_FCNTL;
    }
    memset(&TtyAttr, 0, sizeof(struct termios));
    TtyAttr.c_iflag = IGNPAR;
    TtyAttr.c_cflag = DeviceSpeed | HUPCL | ByteBits | CREAD|CLOCAL;
    TtyAttr.c_cc[VMIN] = 1;

    if (tcsetattr(ncommFd, TCSANOW, &TtyAttr) < 0)
    {
         Warning("Unable to set comm port");
    }
    FD_ZERO(&g_ReadSetFD);
    FD_SET(ncommFd, ReadSetFD);
    return 0;

②send
write(ncommFd, バッファ, 長さ);
③recv
read(ncommFd, バッファ, 長さ);

最後Windows
WindowsでC言語で上のコードを通しても失敗する(コンパイルエラー)
さらに/dev/ttyUSB0というファイルもできないし。
WINDOWSでシリアルポートの情報は実はレジストリからとりそのあとCreateFileでオープンするのだがそんなことはやってられない。
そこでQtでコーディングする方法をしらべると
qextserialportというものが公開されているのが分かる。
これは超便利なクラスでQtのシリアルアクセスをカプセル化します。
http://code.google.com/p/qextserialport/
そこでこれを使って上記コードを書き換えます

環境整備
上記からファイルを落とし展開
C:\qextserialport-1.2beta1\
に展開したとする。
プロジェクトの*.proに
include(C:\qextserialport-1.2beta1\src\qextserialport.pri)
を一行追加して保存

①ポートオープン
#include "qextserialenumerator.h"
//検索
    QList<QextPortInfo> ports = QextSerialEnumerator::getPorts();
    QString enumName;
    char ch_enumName[20];
    char ch_portname[20];
    char ch_com9[20]="COM9";
    printf("List of ports:\n");
    for (int i = 0; i < ports.size(); i++) {
            printf("port name: %s\n", ports.at(i).portName.toLocal8Bit().constData());
            printf("friendly name: %s\n", ports.at(i).friendName.toLocal8Bit().constData());
            printf("physical name: %s\n", ports.at(i).physName.toLocal8Bit().constData());
            printf("enumerator name: %s\n", ports.at(i).enumName.toLocal8Bit().constData());
            printf("===================================\n\n");
            sprintf(ch_enumName,"%s",ports.at(i).enumName.toLocal8Bit().constData());
            if(strcmp(ch_enumName,"USB")==0)
            {
                sprintf(ch_portname,"%s",ports.at(i).portName.toLocal8Bit().constData());
                if(strcmp(ch_portname,ch_com9))
                {
                    sprintf(portname,"\\\\.\\%s",ch_portname);
                }
                break;
            }else{
                sprintf(portname,"%s",ports.at(i).portName.toLocal8Bit().constData());
            }
    }
//open
    QextSerialPort *port = new QextSerialPort(portname);
    port->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
    qDebug("is open: %d", port->isOpen());
    if(port->isOpen() != 1)
    {
        return;
    }
    port->setBaudRate(BAUD9600);
    port->setFlowControl(FLOW_OFF);
    port->setParity(PAR_NONE);
    port->setDataBits(DATA_8);
    port->setStopBits(STOP_1);
    //set timeouts to 500 ms
    port->setTimeout(0);

②send
port->write(バッファ, ながさ);
③recv
port->read(バッファ, ながさ);

ZIP圧縮のプログラム

今回は再びプログラミングの話

ZIP圧縮ルーチンをDLLなどつかわず自力で書きました。
だからその覚書をのこしておきたい。
以下はvisual studio 2010で行いました。

参考にしたのはこれ
http://hp.vector.co.jp/authors/VA016379/cpplib/zlib.htm
http://www.tnksoft.com/reading/zipfile/arczip.php

まず必要なものとしてZLIB(http://www.zlib.net/)があります。
最初にこれをダウンロード(現在zlib127.zip)します。

次に適当なLIBプロジェクトを作成してその中にzlib127.zipを解凍して
できた中身のルートのファイルを(サブフォルダをの中のもの以外)すべて追加

最後にコンパイルしてLIBをを得ます。このときプリコンパイルヘッダをOFFでしないとエラーになります。
ここではこれをzlib.lib(release),zlibd.lib(debug)とします。

次にこれを使用するアプリを作成します。

適当なDLGベースのアプリを作成、ボタンを一個置きます。

次にzlib.libをこのプロジェクトに追加します。
ファイルをプロジェクトにコピー後
プロジェクトの設定で追加してもいいですが
プロジェクトのファイルに
#ifdef _DEBUG
#pragma comment(lib,"zlibd.lib")
#else
#pragma comment(lib,"zlib.lib")
#endif
と書いたほうが、うざくなくて私はすきです。

次にヘッダー類のコピーですが、
zconf.h
zlib.h
をコピーします。
そのまま使ってもいいわけですが、
http://www.tnksoft.com/reading/zipfile/arczip.php
から拝借した
ziputil.cpp
ziputil.h
を経由して使いました。
結局プロジェクトには
#include "ziputil.h"
とかけばいいです。

さらにZIPのファイル情報を管理するMFCクラスを作成しました

class CZipFileInfo : public CObject
{
public:
    CZipFileInfo();
    virtual ~CZipFileInfo();
    CStringA strpath;
    int buflen;
    unsigned char  *buff;
    __time64_t filetime;
};

typedef CTypedPtrArray< CPtrArray, CZipFileInfo* > CZipFileInfoArray;


これでようやく環境が整ったのでコーデイング出来ます。
2関数作成しました
//ZIPファイル検索
void SearchPath(CString strpath,CString strCur,CZipFileInfoArray &  ZipInfoArry){
    CFileFind FileFind;
    BOOL FndEndJug;


    //-----------------------------
    //検索ファイル名文字列を生成
    CString strSearchFile = strpath + _T("\\*.*") ;
   
    //----------------
    //検索実行
    if(!FileFind.FindFile(strSearchFile))
        return;
   
    FndEndJug = TRUE;
    while(FndEndJug){
       
        //-------
        //検索
        FndEndJug = FileFind.FindNextFile();
       
        // "." , ".."を無視
        if(FileFind.IsDots())
            continue;
       
        //検索結果の判定
        if(FileFind.IsDirectory())
        {
            // サブ・ディレクトリ内を検索するための再帰呼び出し
            SearchPath(FileFind.GetFilePath(),strCur,ZipInfoArry);
        }
        else {
            // 検索結果をリスト・ボックスへ出力
            CString fullpath=FileFind.GetFilePath();
            //TRACE(fullpath+L"\n");
            TCHAR RelativePath[MAX_PATH];
            PathRelativePathTo(RelativePath,strCur, FILE_ATTRIBUTE_DIRECTORY,fullpath,FILE_ATTRIBUTE_ARCHIVE);


            //ファイルデータ取り出し
            struct _stat64i32 st0;
            _wstat(fullpath,&st0);
            FILE * fp0=NULL;
            _tfopen_s(&fp0,fullpath,L"rb");
            unsigned char * buff=new unsigned char [st0.st_size];
            fread(buff,1,st0.st_size,fp0);
            fclose(fp0);


            CZipFileInfo * pInfo=new CZipFileInfo;
            pInfo->strpath=RelativePath;
            pInfo->buflen=st0.st_size;
            pInfo->buff=buff;
            pInfo->filetime=st0.st_mtime;
            ZipInfoArry.Add(pInfo);
        }
    }
}

//圧縮
void CreateZip(CString strpath,CString strZip){
    TCHAR chCur[MAX_PATH];
    GetCurrentDirectory(MAX_PATH,chCur);

    //ファイルをサーチ
    CZipFileInfoArray  ZipInfoArry;
    SearchPath(strpath,chCur,ZipInfoArry);
    //ファイル数
    int nLen=ZipInfoArry.GetCount();
    if(nLen<=0)return;
    // ヘッダ情報の作成
    ZipHeader * zipheader=new ZipHeader  [nLen];
    CentralDirHeader * archeader=new CentralDirHeader [nLen];
    memset(zipheader, 0, sizeof(ZipHeader) * nLen);
    memset(archeader, 0, sizeof(CentralDirHeader) * nLen);


    for(int i=0;i<nLen;i++){
        TRACE(ZipInfoArry[i]->strpath+"\n");
        zipheader[i].signature = ZIPSIG_CENTDIR;    // PK0304
        zipheader[i].needver = 20;                    // Deflate圧縮を利用できるVer
        zipheader[i].comptype = 8;                    // Deflate圧縮

        // ファイル時刻を取得
        __time64_t time64=ZipInfoArry[i]->filetime;
        tm nowtm;
        _localtime64_s(&nowtm,&time64);

        zipheader[i].filedate = GetDosDate(nowtm.tm_year + 1900, nowtm.tm_mon+1, nowtm.tm_mday);
        zipheader[i].filetime = GetDosTime(nowtm.tm_hour, nowtm.tm_min, nowtm.tm_sec);

        // 展開時に用いるファイル名の設定
        zipheader[i].fnamelen = ZipInfoArry[i]->strpath.GetLength();
        zipheader[i].filename = ZipInfoArry[i]->strpath.GetBuffer();

        // ファイルサイズの設定
        zipheader[i].uncompsize = ZipInfoArry[i]->buflen;


        archeader[i].signature = ZIPSIG_ARCHIVEFILE;    // PK0102
        archeader[i].madever = 20;



    }

    FILE *fp=NULL;
    _tfopen_s(&fp,strZip, _T("wb"));
    if(fp == NULL){
        printf("ファイルが開けませんでした。");
        return;
    }


    // 圧縮関連変数の初期化
    const uInt tempsize = 16384*0x50;
    Byte * tempbuf=new Byte [tempsize];
    uInt compsize;

    z_stream zs;
    memset(&zs, 0, sizeof(z_stream));

    deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);

    // ファイルの位置を一時的に格納する変数
    unsigned int current;


    // アーカイブデータの書き込み
    InitCRC32();
    for(int i=0;i<nLen;i++){
        // データの位置を格納
        archeader[i].headerpos = ftell(fp);

        // zipヘッダの書き込み
        WriteZipHeader(fp, &zipheader[i]);

        // 現在のファイル位置を一時的に取得
        current = ftell(fp);
   
        // zlib構造体をメモリの開放を行わず再初期化する
        deflateReset(&zs);

        // crc32の初期値は0xFFFFFFFFにする
        zipheader[i].crc32 = CRC32_DEFAULT;

        // データの圧縮と書き込み
        compsize = 0;
        zs.avail_in = zipheader[i].uncompsize;
        zs.next_in = (Bytef*)ZipInfoArry[i]->buff;
        do{
            zs.avail_out = tempsize;
            zs.next_out = tempbuf;

            // CRC32値の更新
            //zipheader[i].crc32 = GetCRC32(zs.next_in, zs.avail_in, zipheader[i].crc32);
            zipheader[i].crc32 = GetCRC32(ZipInfoArry[i]->buff,ZipInfoArry[i]->buflen);

            deflate(&zs, Z_FINISH);

            fwrite(tempbuf, 1, tempsize - zs.avail_out, fp);
        }while(zs.avail_out == 0);


        // 圧縮サイズデータの更新
        zipheader[i].compsize = ftell(fp) - current;

        current = ftell(fp);

        // ファイルデータの書き換え
        fseek(fp, archeader[i].headerpos + 14, SEEK_SET);
        fwrite(&zipheader[i].crc32, 1, sizeof(unsigned int), fp);
        fwrite(&zipheader[i].compsize, 1, sizeof(unsigned int), fp);
        fseek(fp, 0, SEEK_END);


        // ヘッダ内容のコピー
        CopyToCentralDirHeader(&archeader[i], &zipheader[i]);
    }

    // zlibメモリの開放
    deflateEnd(&zs);


    // 中央ディレクトリ情報開始位置の格納
    current = ftell(fp);

    // 中央ディレクトリの書き込み
    for(int i = 0; i < nLen; i++){
        WriteCentralDirHeader(fp, &archeader[i]);
    }

    // 終端ヘッダの書き込み
    EndCentDirHeader endheader;
    memset(&endheader, 0, sizeof(EndCentDirHeader));
    endheader.signature = ZIPSIG_ENDCENTDIR;    // PK0506
    endheader.direntry = nLen;
    endheader.diskdirentry = endheader.direntry;
    endheader.startpos = current;
    endheader.dirsize = ftell(fp) - current;
    WriteEndCentDirHeader(fp, &endheader);

    fclose(fp);
    for(int i=0;i<nLen;i++){
        ZipInfoArry[i]->strpath.ReleaseBuffer();
        delete [] ZipInfoArry[i]->buff;
        delete ZipInfoArry[i];
    }

    delete [] tempbuf;
    delete [] zipheader;
    delete [] archeader;
}

で最後にこれを使う部分をボタンの応答関数に書きます。
void CZIPsampleDlg::OnBnClickedZipRun()
{
    //workのフルパスを作成
    TCHAR cbuff[MAX_PATH];
    ZeroMemory(cbuff,sizeof(cbuff));
    GetCurrentDirectory(MAX_PATH,cbuff);
    lstrcat(cbuff,L"\\work");

    CTime tm=CTime::GetTickCount();
    CString filename=tm.Format("%Y-%m-%d %H-%M.zip");
    CreateZip(cbuff,filename);

}
これでカレントのworkフォルダの中身が現在時刻のファイルに圧縮されます。
ここまで読んでくれた人のためにプロジェクトを添付します。
サンプルプロジェクト