虎之助の徒然記

セブンイレブンアプリ・イトーヨーカドーアプリでログインできない原因は、アカウントが古すぎたこと!

 セブンイレブンアプリ・イトーヨーカドーアプリでログインできない原因がやっと分かりました。

 原因は、あまりにも古いアカウントだったこと。一旦、omni7のホームページにログインして、会員規約に同意、個人情報の確認・更新をすれば、セブンイレブンアプリも、イトーヨーカドーアプリもトラブルなく、ログインできました。

1. アプリにログインできない

 イトーヨーカドーで買い物する際に店員さんに「イトーヨーカドーアプリありますか?」と言われるので、アプリを入れたのですが、ログインできません(涙)。セブンイレブンアプリも同じです。

 セブンイレブンアプリ・イトーヨーカドーアプリの登録には、7iD会員が必要です。

 随分と昔にセブンネットショッピングのために作ったアカウントがありましたが、それが現在は7iD会員にも継承されているとのこと。

 実際、私のセブンネットショッピングに登録したID(メールアドレス)を7iDとして認識しているようでした(新規登録しようとすると、既に登録されていると言われる)。

 古いアカウントだったので、ログインできない原因は、パスワード忘れだろうと、パスワードを更新しましたが、それでもダメ。

 一通り、ネットで検索して原因究明を試みたのですが、解決しませんでした。

 ID・パスワード、アプリのバグ、サーバー側の問題ということではなさそうでした。

2. omni7のホームページにログインしたら解決

 そこで、ブラウザでomni7のホームページでログインしてみました。

 7iDアカウントでログインすると、会員規約への同意や個人情報の確認・更新を求められました。数年ぶりのログインです(たぶん、2012年10月にパスワードを変更して以来なので、6年ぶり)。

 一旦、同意や情報の更新を済ませた後に、セブンイレブンアプリ・イトーヨーカドーアプリに同じ7iDでログインすると、無事にログインすることができました。

f:id:toranosuke_blog:20190201172056p:plain:w250
初ログイン時のメッセージ(セブンイレブンアプリ)

3. 最後に

 ずっと使っていなかったアカウントだったので、新しくなった会員規約に同意していなかったことが、ログインできなかった原因です(たぶん)。

 セブンイレブンアプリ・イトーヨーカドーアプリはログインできないトラブルが多いようですが、以前にセブン&アイ関連のアカウントを作ったことがある方は、omni7のホームページでのでログインを試してはいかがでしょうか?

 ちなみに、omni7のホームページのところに出てくるアイコンは、以下です。

f:id:toranosuke_blog:20190201180611j:plain:w500

 左から、「セブンネットショッピング」「西武・そごう」「イトーヨーカドー」「アカチャンホンポ」「Loft」「セブンイレブンのネットサービス」「デニーズ」「omniモール」。いつのまにか、7iD会員になっているかもしれません。

 ご参考になれば幸いです。

(2019/2/1)



nanacoギフト 10,000円



nanacoギフト 5,000円



nanacoギフト 3,000円

3つのタブレットスタンドを比較した(Anker、Amazon、サンワサプライ)

Anker・Amazon・サンワサプライのタブレットスタンドの3機種についてまとめました。

1. 3つのタブレットスタンド

 いままで購入したタブレットスタンドは、3機種。Anker、Amazonベーシック、サンワサプライのタブレット用のスタンドです。

● Ankerタブレット用スタンド (2014年11月購入)


Ankerタブレット用スタンド

最大負荷5kg
Amazon (販売終了)



Ankerの後継機は、こちら(シルバー:999円、ブラック:1,199円、2019/1/31現在)

● Amazonベーシックタブレットスタンド(2018年9月購入)


Amazonベーシック タブレットスタンド
マルチアングル ポータブルスタンド(タブレット、キンドル、スマートフォン用)

99.1mm×86.4mm×21.6mm、166g、最大負荷4.99kg
シルバー(899円, 2019年1月31日現在)
ブラック(522円, 2019年1月31日現在)

● サンワサプライ iPadスタンド(2014年11月購入)


サンワサプライ iPadスタンド
PDA-STN7W


ポリカーボネート、102mm×84mm×22mm、74g
Amazon(982円, 2019/1/31現在)

製品情報

2. 外観と重さ

f:id:toranosuke_blog:20190131203023j:plain:w500
f:id:toranosuke_blog:20190131203034j:plain:w500
黒がAnker、グレーがAmazon、白がサンワサプライ。

基本的な構造、大きさはほぼ同じ。折りたためば小さくなる。素材は、Ankerはアルミ、Amazonは亜鉛合金、サンワサプライはプラスチックで、サンワサプライは軽い。支えの部分は、いずれもプラスチック。Amazonは、ボディ部分に空間があるので、放熱にもよいのかも。

f:id:toranosuke_blog:20190131203117j:plain:w300 f:id:toranosuke_blog:20190131203011j:plain:w300

FireHD7 (9.6mm)、FireHD8 (9.7mm)、MediaPad X1 7.0 (7.2mm+カバー)を載せた。
サンワサプライは、約1cmのタブレット厚だと、溝におさまらない(iPadはOK)。

f:id:toranosuke_blog:20190131203045j:plain:w200 f:id:toranosuke_blog:20190131203056j:plain:w200 f:id:toranosuke_blog:20190131203106j:plain:w200
Anker Amazon サンワサプライ
179.2g 165.8g 73.7g

 本体が金属製のAnker、Amazonは170g~180g、サンワサプライは、74gです。机に置くのであれば、サンワサプライだと軽く、重いAnkerやAmazonの方が安定感があります。

3. 最後に

 今持っているものの中では、Anker・Amazonは、同じような使い勝手ですが、Ankerの方がお気に入りです。Amazonのシルバーは安っぽく感じます。黒だったらどちらでもよいのかも。サンワサプライは、軽いので持ち運びにはいいのかもしれませんが、据え置きで使うなら重い方が安定します。

 次に購入するとしたら、重く安定し、522円と安いAmazonのブラックです。

(2019/1/31)

その他の製品

 同様の構造のタブレット用スタンドには、他にUGREEN、JEDirect、DAMENG、Tecbossの製品があります。

  • UGREEN
    • ABS樹脂製、107mm×120mm、40.8g、最大負荷550g
    • 40gと軽量で、最大負荷が550gと小さい。華奢か?
    • スマホ用の製品もあるので、要注意(最大負荷350g)。
  • JEDirect
    • アルミ素材、100mm×90mm×40mm、198g、最大負荷6kg。
  • DAMENG
    • ABS素材、120mm×78mm×14mm、28g、最大負荷5kg。
    • 超軽量!(だけど、華奢じゃないのかな?)
  • Tecboss
    • アルミ素材、70mm×107mm、90g、最大負荷は不明。
    • 幅が70mmと短い(安定性が悪いかも)

 筆者が知っているブランドは、UGREENだけで、他はこれまで聞いたことはありません。UGREEN製品も、持ってはいませんが。

10ポートのUSB充電器 Anker PowerPort10 を買った

 久しぶりの記事。小ネタです。

1. Ankerの10ポートUSB充電器を買いました

 困ったもので、USB給電が必要なガジェットが溢れています。ポート不足とケーブルがぐちゃぐちゃなので、ポート数が多いUSB充電器を購入し整理することにしました。

 調べたところ、ポート数としては、10ポートが最大のようで、この中から、Ankerの10ポートのUSB充電器(PowerPort10)を購入しました。


Anker PowerPort 10
(60W 10ポート USB急速充電器)


【PSE認証済/PowerIQ搭載】
iPhone XS/XS Max/XR, iPad, Galaxy S9 / S9+ 等対応 (ブラック)

Amazon(3,799円, 2019/1/31現在)

このUSB充電器の特徴は、

  • Anker製品!
  • 各ポート最大2.4AまでOK
  • 全体で60Wまで
  • 急速充電可能

f:id:toranosuke_blog:20190131144010j:plain
製品ホームページより

 実物を見ると、写真で想像していたものよりかなり小型でした。旅行に10台もデバイスを持っていくことはないので、出番はありませんが、旅行鞄にポイっと入れられる大きさです(本体よりもAC電源ケーブルの方がジャマかも)。

 1Aのポートが混在しないのも、良い点です。全部が2A給電となると、2A×5V×10=100W となり、60Wオーバーですが、10台もあると一度にフルに給電する必要もないでしょうし、必要であっても、適当に内蔵回路で調整しているのでしょう。

 Anker製品は、基本的にコストパフォーマンスは悪くはないと思います。

 今回の製品も、最安値の製品よりも1000円以上高くなりますが、このぐらいの差なら、充電回りということもあり、安心できるAnker製品を購入しました(Apple製品は、電源の安定性にうるさい)。

2. 実物は意外と小さい

f:id:toranosuke_blog:20190131113706j:plain:w400
10ポートのUSB充電器
f:id:toranosuke_blog:20190131113734j:plain:w400
タバコよりも一回り大きいぐらいでコンパクト
f:id:toranosuke_blog:20190131113906j:plain:w400
付属品はケーブルと簡単なマニュアルなど

 設置後の写真は、、、整理した後でも、悲惨な状態なので、省略します(笑)。

3. 最後に

 現在、スマホ1台、ファブレット1台、タブレット2台、Amazon Echo1台、携帯ラジオ、電子タバコ(glo)1台の計7台をつなげていますが、特に問題はありません。今のところ、満足しています。

(2019/1/31)

AnkerのUSB充電器

 Ankerの10ポート、6ポート、4ポートの製品。

 4ポートの製品はプラグ式で、旅行などにも持っていって邪魔にならない大きさです。

他社のUSB充電器(10ポート)

タブレット・スマホのスタンドと一体型の充電ステーション。
魅力的だけど、実際には、スマホ・タブレット以外にもいろんなものつなげるからなぁ~。


サンワサプライは高すぎます。それ以外は、筆者は聞いたことがないブランドです。

【Python】numpy 整数の演算結果が float64 に。摩訶不思議なデータ型変換ルール。

【概要】 numpyで扱っていた整数が、いつのまにか float64 の浮動小数になっていました。pyhonでは、被演算子のデータ型の組み合わせによっては、演算結果のデータ型が変更されます。動的型付けの影響です。調べてみると、この変換にはいろいろなパターンがあります。そして、整数の演算同士の演算でも、その結果が浮動小数となる摩訶不思議なデータ型の変換ルールがあることも分かりました。

1. はじめに

 GPTテーブルを読み取るPythonスクリプト(関連記事は、ここ)を書いていて、困ったのが、セクタ数をバイト数に変換する際、numpy.uint64 のつもりの演算結果が float64 の浮動小数になってしまったこと。これでは、ファイルの頭出し ( f.seek() ) ができません。

 とりあえずの解決策は見つけたのですが、動作は良く理解していないままでした。本稿では、uint64の演算がfloat64 へ変換されるケースについて、まず述べます。その後、pythonにおける演算結果のデータ型の割り付け規則についてまとめます。

 なお、本稿は、python3 での動作について述べています。python2 の場合は動作が異なります(付録B参照)。

2. uint64 の演算結果が、float64 になる

2.1 整数が浮動小数になって、f.seek できない

 numpyのfloat32のスカラー値 (numpy.float32) と ( numpy ではない ) 普通のスカラー値の整数 (<class 'int'>) や浮動小数 (<class 'float'>) との演算を行うと、自動的に numpy.float64 の浮動小数になるそうです*1

 このようなデータ型の変更は、numpy.float32に限らず、numpy.unit64の場合にも発生します。

 例えば、セクタ数 (sector=2)をバイト数 (byte=1024) に変換するつもりで以下のように演算すると、byte は numpy.float64 の変数になってしまいます。

>>> import numpy as np
>>>
>>> sector = np.array(2,'uint64')
>>> 
>>> sector
array(2, dtype=uint64)
>>> type(sector)
<class 'numpy.ndarray'>
>>> sector.dtype
dtype('uint64')

この uint64 の numpy の変数 sector を用いて、バイト数に変換して、ファイルを f.seek(sector*512) しようとすると、エラーとなります。

>>> f = open('tmpfile','rb')
>>> f.seek(sector*512)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'numpy.float64' object cannot be interpreted as an integer

 sector*512 は、numpy.float64 の変数になっているようです。

>>> byte = sector*512
>>> byte
1024.0
>>> type(byte)
<class 'numpy.float64'>
>>> byte.dtype
dtype('float64')

 float64 になった値をint() や astype() で整数に変換すればよいのかしれませんが、美しくありません。

2.2 float64 への昇格問題

 これは、型の昇格というpythonの動作によるものです。普通のスカラー値、numpy によるスカラー値 ( 0次元配列)、numpy の配列の3つの場合について、乗算をした結果は、次の表のようになります。

512
<class 'int'>
-
np.array(512,'uint64')
<class 'numpy.ndarray'>
'uint64'
np.array([512],'uint64')
<class 'numpy.ndarray'>
'uint64'
2
<class 'int'>
-
1024
<class 'int'>
-
1024.0
<class 'numpy.float64'>
'float64'
[1024]
<class 'numpy.ndarray'>
'uint64'
np.array(2,'uint64')
<class 'numpy.ndarray'>
'uint64'
1024.0
<class 'numpy.float64'>
'float64'
1024
<class 'numpy.uint64'>
'uint64'
[1024]
<class 'numpy.ndarray'>
'uint64'
np.array([2],'uint64')
<class 'numpy.ndarray'>
'uint64'
[1024]
<class 'numpy.ndarray'>
'uint64'
[1024]
<class 'numpy.ndarray'>
'uint64'
[1024]
<class 'numpy.ndarray'>
'uint64'

乗算結果の上段は、print()の結果、中段はtype()の結果、下段はdtype属性。

 この表から、次のことが分かります。

  • float64 に型変換されるのは、普通のスカラー値 (<class 'int') と numpy のスカラー値との間で演算が行われた場合のみ。
  • それ以外は、すべて整数型のまま。

 整数同士の演算結果が浮動小数に型変換されるのは、奇妙な仕様です。

3. データ型変換のルール

 前節で調べたのは、型の組合せの極一部です。主な整数型、浮動小数型について、プログラムを作って調べました(付録A参照)。

3.1 調べたデータ型

 調査対象は、普通のスカラー値の int ( <class 'int'>)、普通のスカラー値の float( <class 'float'>)、numpy の整数 ( 32ビット、64ビット、符号有無)、浮動小数(32ビット、64ビット )、及び、それらの配列の計14個の型です。

  • 普通のスカラー値のint (i)
  • 普通のスカラー値のfloat (f)
  • numpyのint32 (i4)、uint32 (u4) 、int64 (i8)、uint64 (u8)、及び、それらの配列
  • numpyのfloat32 (f4), float64(f8)、及び、それらの配列

3.2 データ型の変換テーブルと変換ルール

 これらの型の演算結果の組合せは、以下の図のテーブル(マトリックス)に示す通りです。[ ]の場合は、配列です。最上段、最左列がそれぞれの被演算子のデータ型、それぞれの被演算子と演算を行った結果をテーブルにしています。上右三角の部分と左下三角の部分は同じ結果となるので、省略しています。

3.2.1 加算・減算・乗算の場合のデータ型の変換テーブル

 演算は、加算・減算・乗算、いずれの場合も同じ結果です。除算は異なります。

f:id:toranosuke_blog:20180928224221p:plain
 14個のデータ型の演算結果のデータ型。

 i, f は、<class 'int'>、<class 'float'>、それ以外は numpy の型コードによる表記(例えば、i4 であれば int32、[i4] は int32 の配列)。赤は整数が浮動小数に変換される場合、青色は、型の昇格がある場合、オレンジは型の降格がある場合、灰色は符号が変わる場合。赤・青の細線は被演算子のいずれかが昇格・降格の場合、太線は被演算子の両方にとって昇格の場合。スカラー型の int、float は、それぞれ int64、float64 の精度として、昇格・降格を判定。

f:id:toranosuke_blog:20180928193435p:plain

 スカラー値、0次元配列(スカラー値相当)のみ。64ビットの符号なし整数 (uint64) と符号あり整数 (int, int32, int64) の時に64ビットの浮動小数 (float64) に変換される。

f:id:toranosuke_blog:20180928193453p:plain
配列のみ。

3.2.2 加算・減算・乗算の場合のデータ型の変換ルール

 この結果から次の変換ルールがあることが分かります。

  • 型の順位:float64 > float32 > int64, uint64 >int32, uint32
  • スカラー同士の演算
    • 同じ順位の型同士の演算で、型は変わらない。
    • float32、float64との演算 ⇒ float64
    • 符号なし整数と符号あり整数の演算は、昇格する。
      • uint32 と int32 ⇒ int64
      • uint64 とint, int32, int64 ⇒ float64
    • 型の順位が異なる場合は、順位が上位の型に合わせる
      • int32とint64 ⇒ int64
      • uint32とint64 ⇒ int64
      • uint32とuint64 ⇒ uint64
  • 配列とスカラーの演算
    • float32の配列とスカラーの演算 ⇒ float32の配列
    • float64の配列とスカラーの演算 ⇒ float64の配列
    • 整数配列とfloat32, float64の演算 ⇒ float64の配列
    • 整数配列と整数型スカラーの演算 ⇒ 入力配列の型と同じ型の配列
       スカラーの型順位が上位の場合、スカラーのデータ型が降格する。
  • 配列と配列の演算
    • スカラー同士の演算に準じる。

 動的型付けの演算では、何らかの変換ルールで、演算結果のデータ型を決める必要があります。uint64 と符号あり整数型の演算の場合を除けば、概ね理解できる変換ルールです。

 符号なし整数と符号ありの整数は昇格させるという基準で設定されている変換ルールと思いますが、だからと言って、昇格した先のデータ型が浮動小数というのは、理解しがたい仕様です。

3.2.3 除算の場合のデータ型の変換ルール

 除算の場合の変換テーブルは、以下の図の通りです。

f:id:toranosuke_blog:20180928230322p:plain
除算のデータ型。

 変換ルールは、次の通りです。

  • 除算の場合は、基本的にfloat64を出力する。
  • 但し、
    • float32とfloat32の演算 ⇒ float32
    • float32の配列とfloat32の配列 ⇒ float32の配列
    • float32の配列とスカラーの演算 ⇒ float32の配列

3.3 摩訶不思議なデータ型の変換ルール

 pythonは予め出力のデータがを決めない動的型付けのため、被演算子に基づき決めた何らかのデータ変換ルールに従って、演算を行う必要があります。そのデータ変換ルールが、前節で説明したような変換ルールだったわけです。

 概ね、理解できる変換ルールですが、整数同士の演算を浮動小数点に昇格させてしまうのは、直感的に予想できない変換ルールです。また、uint64 の主たる使用目的の一つはアドレス指定と思います。

 そうであれば、uint64を浮動小数へ変換するルールは、奇異なルール、摩訶不思議なルールと言わざるを得ません。

 浮動小数で困る場合には、int() や astype() などで整数型へ変換を行えば済む話かもしれません。それでも、float64 への昇格ではなく、64ビットの整数への変換の方が分かりやすく、適切な仕様ではないでしょうか。

4. 最後に

 pythonのデータ型の変換についてまとめました。pythonでは、uint64型と符号あり整数型の演算が浮動小数に変換されるという摩訶不思議なデータ型の変換ルールがあり、注意が必要です。

 私のような Python 初心者でなくても、はまりそうな点ではないかと思います。

(2018/9/29)

関連記事

付録A:演算結果のデータ型を表示するスクリプト

 python3のスクリプトです。動作確認は、ubuntu18.04で行っています。

 python2のスクリプトも作っています(python3との違いは、print文の関係のみ)。python2のスクリプトと実験結果と合わせて、ここ (Googleドライブ) に置いておきます。

#!/usr/bin/python3
#
# ckeck_types.py
# 
# make tables of data types converted with operation in python. 
#
# copyright (c) 2018 Toranosuke Tenyu

import sys
import numpy as np

def add_bra(cc,bra=False):

    if bra == True:
        return "["+cc+"]"
    else:
        return cc

def cc (dd):

    ti = type(2)
    tf = type(2.0)

    bra = "[" in "{}".format(dd)

    if hasattr(dd,"dtype"):
        code = dd.dtype
        if code == 'int32':
            return add_bra('i4',bra)
        if code == 'uint32':
            return add_bra('u4',bra)
        if code == 'int64':
            return add_bra('i8',bra)
        if code == 'uint64':
            return add_bra('u8',bra)
        if code == 'float32':
            return add_bra('f4',bra)
        if code == 'float64':
            return add_bra('f8',bra)
    else:
        code = type(dd)
        if code == ti :
            return 'i'
        if code == tf :
            return 'f'

def print_dtype(dd,dd_print=False):

    if dd_print:
        print("%5s"%dd,"%5s"%cc(dd),end=" ")
    else:
        print("%5s"%cc(dd),end=" ")
            

def print_conv(data,dd_print=False,dd_trig=True,op="mul"):

    if dd_print:
        print("%10s"%"",end="  ")
    else:
        print("%5s"%"",end=" ")

    for dd in data:
        print_dtype(dd,dd_print)

    print("")

    for dd2 in data:
        print_dtype(dd2,dd_print)

        for dd1 in data:

            if op == "mul":
                val = dd2*dd1
            elif op == "add":
                val = dd2+dd1
            elif op == "sub":
                val = dd2-dd1
            else:
                val = dd2/dd1
                
            print_dtype(val,dd_print)
            if dd_trig :
                if cc(dd1) == cc(dd2):
                    break

        print("")
            

        
if __name__ == '__main__': 

    i2 = 2
    f2 = 2.0

    # print orignal data
    # dd_print = True
    dd_print = False

    # print only lower triangular matrix
    dd_trig = True
    #dd_trig = False

    op = "mul"
    # op = "add"
    # op = "sub"
    # op = "div"

    print(sys.version)

    print("")
    
    data = [
        i2,
        f2,
        np.array(i2  ,'i4'),
        np.array([i2],'i4'),
        np.array(i2  ,'u4'),
        np.array([i2],'u4'),
        np.array(i2  ,'i8'),
        np.array([i2],'i8'),
        np.array(i2  ,'u8'),
        np.array([i2],'u8'),
        np.array(f2  ,'f4'),
        np.array([f2],'f4'),
        np.array(f2  ,'f8'),
        np.array([f2],'f8')
    ]
    print_conv(data,dd_print,dd_trig,op)
    print("")

    data = [
        i2,
        f2,
        np.array(i2  ,'i4'),
        np.array(i2  ,'u4'),
        np.array(i2  ,'i8'),
        np.array(i2  ,'u8'),
        np.array(f2  ,'f4'),
        np.array(f2  ,'f8')
    ]
    print_conv(data,dd_print,dd_trig,op)
    print("")

    data = [
        np.array([i2],'i4'),
        np.array([i2],'u4'),
        np.array([i2],'i8'),
        np.array([i2],'u8'),
        np.array([f2],'f4'),
        np.array([f2],'f8')
    ]
    print_conv(data,dd_print,dd_trig,op)
    print("")

付録B. python2との違い

 python2とpython3で加算・乗算・乗算については、同一動作でした。

 しかし、除算については、python3と動作が異なります。変換テーブルは、以下の通りです。

f:id:toranosuke_blog:20180929153135p:plain
Python2の除算演算における変換規則。

 この変換規則は、加算・減算・乗算の変換規則と同一です。つまり、python2では四則演算の全てで同じ変換規則を使っています。

 一方、python3では、加算・減算・乗算に関しては、python2と同じですが、除算に関しては、基本的に float64 を出力するように変更されています。

 つまり、python2とpython3の違いは、除算結果のデータ型の変換ルールの違いとなります。

GPTテーブルを読み取るプログラムを作って、Windowsディスクを調べた(in Python)

【概要】GPTテーブルを読み取って、テキストで出力する Python プログラムを作りました。gdisk ではテキスト出力できない GPT ヘッダの位置を読み出す目的で作りましたが、GPT テーブル内に入っている他の情報もすべて出力します。このプログラムを使って、Windows でディスクのパーティションテーブルが正常に設定されているか、調査しました。

1. はじめに

 クローンディスクを作っていて気になったのが、Windowsでは、GUIDパーティションテーブル (GUID Partition Talbe; GPT) の第2GPTヘッダを正しい位置、つまり、ディスクの末尾に配置しているか、という点です(関連記事は、ここ)。

 Windowsで作ったディスクを gdisk で覗くと、次のエラーメッセージが出力されます。

The protective MBR's 0xEE partition is oversized! Auto-repairing.

 gdisk のソースコードを読めばいいのかもしれませんが、この原因をよく理解していませんでした。パーティションサイズの認識に何らかの異常があるのですが、このエラー自体は深刻なものではなく、自動修復しても構わない程度のもののようです*1

 最初に疑ったのは、Windows。Windowsでは認識したことになっているディスクサイズが実際のディスクサイズと違うのではないか?その影響が、先のエラーメッセージとなって現れたと推測しました。このことを確認する一つの方法が、第2GPTヘッダの位置が適切な場所、つまり、ディスク末尾に置かれているか、ということです。

 GPTテーブルを読み取るプログラムは、このような背景から生まれました。

 なお、使用した言語は、Pythonです。Python 初心者なので、変なところがあると思います。ご指導・ご鞭撻のほどよろしくお願い致します。

2. Pythonプログラム

2.1 仕様

 GPTヘッダの情報を全てテキストで出力します。入力は、dd ダンプしたハードディスクイメージか、gdisk で保存したGPTデータです。

 gdisk の CUI で取り出せない主なデータは、第1と第2のGPTヘッダの位置情報とCRCの値、MBRぐらいです。それ以外の情報は、gdiskでもほぼすべてテキスト出力できます。

 今回作った read-gpt-table.py では、gdisk でテキスト出力できない GPTヘッダの位置情報を含めて、すべてのデータを出力します。

 目的や入出力が異なりますが、GPTテーブルを読み出すCのプログラムもあります。今回の目的には合致しませんでしたが、参考にさせて頂きました。
 ● GUID Partition Table を読む - jou4のブログ

2.2 コード

 GPTテーブルを読み取るためのプログラム read-gpt-table.py を付録A につけておきます。使い方は、次の通りです。

$ read-gpt-table.py 
Usage: read-gpt-table.py file [option]
 Read GPT table from file.
 Option:
  --dd    : file is a dd-dumped image. (default)
  --gdisk : file is a GPT table saved by gdisk.

 Caution:
     gdisk may repair GPT header automatically.
     To get GPT header as is, use dd-dumped image.

 注にも書きましたが、gdiskでは、自動的にGPTヘッダを修復してしまうことがあるので、変更を加えないそのままのGPTヘッダを読み取りたい場合には、ddダンプしたファイルを使った方がよいです。

 なお、動作確認は、ubuntu/lubuntu 18.04 の pyhonの3.6.6で行っています。

2.3 使い方

● ddダンプしたファイルの場合

$ dd if=/dev/sdX of=foo.img
$ read-gpt-table.py foo.img --dd 

● gdiskのGPTデータの場合

$ gdisk /dev/sdX
 ( command 'b' を実行し、foo.gpt に保存 )
$ read-gpt-table.py foo.gpt --gdisk

3. WindowsのGPTテーブルを調べた

3.1 gdiskで保存されるGPTテーブル

 GPTテーブルのほとんどの情報は、gdiskのCUIから読み出すことができます。しかし、筆者が知りたかったGPTヘッダの位置情報については、CUIからは調べることはできません。

 一方、gdiskのコマンド 'b' によって保存されたバイナリのファイルには、GPTテーブルのすべての情報が保存されますので *2、このバイナリファイルを解析することで、知りたい情報を得ることができます。

 このデータファイルの構造は、下記の計35セクタ ( =17,920 バイト)です。

  • [MBR(1), 第1GPTヘッダ(1), 第2GPTヘッダ(1), パーティションエントリー(32)]
 ddダンプしたファイルでは、ファイルの先頭に [MBR, 第1GPTヘッダ, パーティションエントリー]の計34セクタが配置され、第2GPTヘッダやパーティションエントリーのコピーはディスク末尾に配置されますので、プログラミングの際には、少々、注意を払う必要があります。

 但し、gdiskが保存するGPTデータは、メモリ上に展開されたパーティション情報です。gdiskのマニュアルには、バックアップコマンド b について以下の説明があります。

Save partition data to a backup file. You can back up your current in-memory partition table to a disk file using this option. The resulting file is a binary file consisting of the protective MBR, the main GPT header, the backup GPT header, and one copy of the partition table, in that order. Note that the backup is of the current in-memory data structures, so if you launch the program, make changes, and then use this option, the backup will reflect your changes.

 この説明を読むと、前述の "Auto-repairing" が実施された場合にも、自動修復された状態のGPTテーブルがファイルに出力されそうです。

3.2 WindowsのGPTテーブルに異常なし

 次の二つのディスクについて、GPTテーブルを調査しました。

  • Windowsシステムが入った1TBのHDD
  • Windowsシステムが入った500GBのSSD

 プログラムの出力例を付録Bに示します。

 HDDの場合でも、SSDの場合でも、ddダンプしたファイルから読み取ったGPTテーブルと、gdiskのGPTデータから読み取ったGPTテーブルとの間では、MBRの極一部を除き同一でした。

 一番気になっていた第2GPTの位置ですが、ディスク末尾の最終セクタへのオフセット値を示していて、正常です。また、ddダンプしたディスクイメージの末尾の1セクタ(512バイト)から読み込んだ第2GPTテーブルにも異常は見られませんでした。

 Windowsが作ったパーティションテーブルだからと言って、GPTについては、おかしなことをやっているわけではなさそうです。

 但し、「GPTについては」です。

3.3 WindowsのMBRはいい加減

 gdiskの結果とddの結果で異なる部分は、MBRの部分でした。これは、MBRの第1パーティションの全セクタ数で、例えば、SSDの場合には以下となります。

バイト数ddの値
(修復前)
gdiskの値
(修復後)
ブートフラグ 1 0x 00
最初のセクタ(CHS方式) 3 0x 00 20 00
パーティション識別子 1 0x EE (=GPT)
最後のセクタ(CHS方式) 3 0x FF FF FF
最初のセクタ(LBA方式) 4 0x 00 00 00 01
パーティションの全セクタ数4 0x FF FF FF FF 0x 3A 38 60 2F
(=976,773,167)
MBRの第1パーティションの情報 (500GBのSSDの場合)。

 Windowsの場合、パーティションの最初のセクタ数(LBA)は正しいようですが、パーティションの全セクタ数は実際の数字を反映せず、0xFFFFFFFFが設定されています。

 gdiskは、パーティションサイズが0xFFFFFFFFというのは大きすぎる (The protective MBR's 0xEE partition is oversized!) と判定し、自動修復(Auto-repairing) して、GPTが管理するセクタ数(=ディスクの全セクタ数-1)をMBRの第1パーティションの全セクタ数として設定しているようです。HDDの場合も同様に修正されています。

 Windowsとしては、パーティションサイズが-1 (0xFFFFFFFF) という設定は、サイズ不明ということなのでしょう。パーティションサイズを取得できないわけではないので、手抜き実装としか思えません。

 CHS方式のセクタ数も不正確と思いますが、gdisk は修復していません。CHS方式でのディスク管理は廃れた方式なので、gdisk も相手にしなかったということでしょうね。

 やはり、Windows。MBR については、いい加減な実装をしていました。

4. 結論

 Windowsでは、第2GPTヘッダーが正しく配置されないという疑念がありましたが、特に問題なさそうです。

 但し、WindowsのMBRのパーティションサイズは正しく入力されていません。gdiskでは、Windowsが設定した不適切なのMBRの値を自動的に正しい値に設定し直しているようです。

 モヤモヤしていたことなので、疑念が晴れてスッキリしました。また、Pythonの勉強にもなりました。

(2018/9/24)

関連記事

付録A:GPTテーブルを読み取るPythonプログラム

ソースコードとサンプルデータは、ここ(Googleドライブ)に置いておきます。

#!/usr/bin/python3
#
# read-gpt-table.py
# 
#   Read and print GPT partition table from a file saved with dd or gdisk.
# 
#   Copyright (C) 2018 Toranosuke Tenyu
#
#

### structure of GPT table in dd-dumped image ###
# LBA0       is MBR
# LBA1       is 1st GPT Header
# LBA2-33    is partition entries (128 entries)
# last LBA   is 2nd GPT Header (the end of disk)
#
# see:  https://en.wikipedia.org/wiki/GUID_Partition_Table

### structure of GPT table in GPT data saved with gdisk ###
#
# LBA0       is MBR
# LBA1       is 1st GPT Header
# LBA2       is 2nd GPT Header
# LBA3-LBA34 is partition entries (128 entries)
#
# The size of GPT data by gdisk is 35 sectors (17920 bytes)
# The size of LBA is 1 sector.

import sys
import numpy as np

### gpt header dtype (512 byte)
gpt_dtype = np.dtype([
    ('signature',          'S8'),
    ('revision',           '>u4'),
    ('header_size',        '<u4'),
    ('crc32_1',            '<u4'),
    ('reserved_1',         '<u4'),
    ('loc_1st_gpt',        '<u8'),
    ('loc_2nd_gpt',        '<u8'),
    ('first_usable_sector','<u8'),
    ('last_usable_sector', '<u8'),
    ('disk_guid',          'u1',16),
    ('starting_lba',       '<u8'),
    ('num_of_entry',       '<u4'),
    ('size_of_entry',      '<u4'),
    ('crc32_2',            '<u4'),
    ('reserved_2',         'u1',420)
])

### read GPT Header 
def read_gpt(filename, offset=512):

    # open gpt file
    fp = open(filename,'rb')
    fp.seek(offset)

    # read GPT Header from file
    gpt = np.fromfile(fp,dtype=gpt_dtype,count=1)

    # close file
    fp.close()

    return gpt

### print GPT Header ###
def print_gpt(gpt):
    print('signature             : %s' %gpt['signature'].tostring().decode('ascii'))
    print('revision              : 0x%08x'%gpt['revision'][0])
    print('header size           : %d'%gpt['header_size'])
    print('crc32(1)              : %d'%gpt['crc32_1'])
    print('reserved(2)           : %d'%gpt['reserved_1'])
    print('1st GPT location      : %d'%gpt['loc_1st_gpt'])
    print('2nd GPT location      : %d'%gpt['loc_2nd_gpt'])
    print('first usable sector   : %d'%gpt['first_usable_sector'])
    print('last usable sector    : %d'%gpt['last_usable_sector'])
    print('disk_guid             : %s'%guid_toString(gpt['disk_guid'][0]))
    print('starting LBA          : %d'%gpt['starting_lba'])
    print('number of entry       : %d'%gpt['num_of_entry'])
    print('size of entry         : %d'%gpt['size_of_entry'])
    print('crc32(2)              : %d'%gpt['crc32_2'])

# Convert binary GUID to string
def guid_toString(guid):

    # print(guid)

    guid_ascii =''

    # data1 (ulong)
    guid_ascii += f'%02X'%guid[3]
    guid_ascii += f'%02X'%guid[2]
    guid_ascii += f'%02X'%guid[1]
    guid_ascii += f'%02X'%guid[0]
    guid_ascii += '-'

    # data2 (ushort)
    guid_ascii += f'%02X'%guid[5]
    guid_ascii += f'%02X'%guid[4]
    guid_ascii += '-'

    # data3 (ushort)
    guid_ascii += f'%02X'%guid[7]
    guid_ascii += f'%02X'%guid[6]
    guid_ascii += '-'

    # data4 (uchar[8])
    guid_ascii += f'%02X'%guid[8]
    guid_ascii += f'%02X'%guid[9]
    guid_ascii += '-'
    guid_ascii += f'%02X'%guid[10]
    guid_ascii += f'%02X'%guid[11]
    guid_ascii += f'%02X'%guid[12]
    guid_ascii += f'%02X'%guid[13]
    guid_ascii += f'%02X'%guid[14]
    guid_ascii += f'%02X'%guid[15]

    return guid_ascii

### partition entry (128 byte/entry) ###

entry_dtype = np.dtype([
    ('type_guid',      'u1',16),
    ('unique_guid',    'u1',16),
    ('first_lba',      '<u8'),
    ('last_lba' ,      '<u8'),
    ('attribute_flag', '<u8'),
    ('partition_name', '<u2',36)
])

def read_entry(filename,offset=1024,npart=-1):

    # open file
    fp = open(filename,'rb')
    fp.seek(offset)

    # read partition entry from file
    entry = np.fromfile(fp,dtype=entry_dtype,count=npart)
    
    # close file
    fp.close()

    return entry

def print_entry(entry):

    count = 0
    for item in entry:
        if item['first_lba'] != 0 :
            print('partition type guid   :', guid_toString(item['type_guid']))
            print('unique partition guid :', guid_toString(item['unique_guid']))
            print('first_lba             :', item['first_lba'])
            print('last_lba              :', item['last_lba'])
            print('attribute flags       : 0x%016X'%item['attribute_flag'])
            print('partition name        : \'{}\''.format(item['partition_name'].tostring().decode('utf-16-le').strip('\0')))
            print('')
            count += 1

    print('Number of valid entries = %d\n'%count)

### MBR ###
def read_mbr(filename,offset=0):
    fp = open(filename,'rb')
    fp.seek(offset)
    
    mbr = np.fromfile(fp,dtype='<u1',count=512)
    fp.close()
    return mbr

def print_mbr(mbr):
    count=1
    for item in mbr :
        if item != 0 :
            print('%02X '%item,end='')
        else :
            print('-- ',end='')
        if count%16 == 0 :
            print('')
        count += 1
    print(' ')

def print_usage():
    print('Usage: {} file [option]'.format(__file__))
    print(' Read GPT table from file.')
    print(' Option:')
    print('  --dd    : file is a dd-dumped image. (default)')
    print('  --gdisk : file is a GPT table saved by gdisk.')
    print('')
    print(' Caution:')
    print('     gdisk may repair GPT header automatically.')
    print('     To get GPT header as is, use dd-dumped image.')

def args_parser():
    args = sys.argv

    if (len(args) == 2 ):
        return 'dd'         # read GPT table from dd-dump (default)

    if (len(args) == 3):
        if ( args[2] == '--gdisk' ):
            return 'gdisk'   # read GPT table  saved by gdisk
        if ( args[2] == '--dd' ):
            return 'dd'

    print_usage()
    sys.exit()

if __name__ == '__main__':

    # set file_type = 'dd' or 'gdisk'
    file_type = args_parser()

    filename = sys.argv[1]

    bsize = 512

    ### read & print GPT header

    if ( file_type == 'gdisk' ):

        # read from gdisk file 

        print('### 1st GPT Header ###')
        gpt_header1 = read_gpt(filename,bsize)
        print_gpt(gpt_header1)
        print('')

        print('### 2nd GPT Header ###')
        gpt_header2 = read_gpt(filename,2*bsize)
        print_gpt(gpt_header2)
        print('')

        print('### Partition Entry ###')
        entry_list = read_entry(filename,3*bsize)
        print('Number of entries = %d\n'%entry_list.size)
        print_entry(entry_list)

        print('### MBR ###')
        mbr = read_mbr(filename,0)
        print_mbr(mbr)
    else:
        # read from dd-dump file        

        print('### 1st GPT Header ###')
        gpt_header1 = read_gpt(filename,bsize)
        print_gpt(gpt_header1)
        print('')

       print('### 2nd GPT Header ###')

        # escape from converting into float64
        uint64_512 = np.array([512],dtype=np.uint64)
        uint64_loc = gpt_header1['loc_2nd_gpt'][0]*uint64_512[0]
        
        gpt_header2 = read_gpt(filename,uint64_loc)
        print_gpt(gpt_header2)
        print('')

        print('### Partition Entry ###')
        entry_list = read_entry(filename,2*bsize,128)
        print('Number of entries = %d\n'%entry_list.size)
        print_entry(entry_list)
        
        print('### MBR ###')
        mbr = read_mbr(filename,0)
        print_mbr(mbr)

    sys.exit()

付録B:read-gpt-table.pyの実行結果

### 1st GPT Header ###
signature             : EFI PART
revision              : 0x00000100
header size           : 92
crc32(1)              : 2997411310
reserved(2)           : 0
1st GPT location      : 1
2nd GPT location      : 1953525167
first usable sector   : 34
last usable sector    : 1953525134
disk_guid             : B45D2A5C-F9A4-478D-818B-D8E6280ABEA4
starting LBA          : 2
number of entry       : 128
size of entry         : 128
crc32(2)              : 3723135598

### 2nd GPT Header ###
signature             : EFI PART
revision              : 0x00000100
header size           : 92
crc32(1)              : 288711948
reserved(2)           : 0
1st GPT location      : 1953525167
2nd GPT location      : 1
first usable sector   : 34
last usable sector    : 1953525134
disk_guid             : B45D2A5C-F9A4-478D-818B-D8E6280ABEA4
starting LBA          : 1953525135
number of entry       : 128
size of entry         : 128
crc32(2)              : 3723135598

### Partition Entry ###
Number of entries = 128

partition type guid   : C12A7328-F81F-11D2-BA4B-00A0C93EC93B
unique partition guid : CC2D4D60-A1FB-4D4E-9542-C603A9BA1CCD
first_lba             : 2048
last_lba              : 534527
attribute flags       : 0x8000000000000000
partition name        : 'EFI system partition'

partition type guid   : E3C9E316-0B5C-4DB8-817D-F92DF00215AE
unique partition guid : 91297EAC-45C5-4BDC-8F28-CC0978A7084F
first_lba             : 534528
last_lba              : 567295
attribute flags       : 0x8000000000000000
partition name        : 'Microsoft reserved partition'

partition type guid   : EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
unique partition guid : 79886FBF-71C1-4E37-9922-A2C336CA8720
first_lba             : 567296
last_lba              : 1926947658
attribute flags       : 0x0000000000000000
partition name        : 'Basic data partition'

partition type guid   : DE94BBA4-06D1-4D40-A16A-BFD50179D6AC
unique partition guid : 6ABF2C3A-3420-48A2-968D-5F3FCBA7EF1B
first_lba             : 1926948864
last_lba              : 1929021439
attribute flags       : 0x8000000000000001
partition name        : ''

partition type guid   : DE94BBA4-06D1-4D40-A16A-BFD50179D6AC
unique partition guid : 932D4253-8484-440A-856C-2A8E03037CBE
first_lba             : 1929022863
last_lba              : 1953525134
attribute flags       : 0x8000000000000001
partition name        : 'Basic data partition'

Number of valid entries = 5

### MBR ###
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
02 -- EE FF FF FF 01 -- -- -- FF FF FF FF -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- 55 AA 

*1:"The oversized 0xEE partition ...(snip)... could indicate something strange to do with disk size detection." (Rod Smith, gdiskの開発者)
https://superuser.com/questions/1023343/after-upgrading-from-windows-7-to-windows-10-system-thinks-gpt-partition-is-mbr#comment1424307_1023702

*2: GPTテーブルの構造については、「GUIパーティションテーブル」(wikipedia)やその英語版に解説があります。これを参考にしました。

Win10 1803 が VirtualBox にも悪さした

【概要】 Windows10の1803アップグレードで、CryptSvc が原因で chrome が動作異常を起こすことを報告しましたが、VirtualBox にも悪影響を与えていました。とりあえずの回避方法を紹介します。

1. Windows10 1803アップグレード

 何かと安定しないと言われる1803アップグレード。既にChromeについての異常動作については紹介しました(関連記事は、ここ)。

 この原因は、CryptSvcの暴走ですが、VirtualBoxでも、起動時にCryptSvcが暴走し、正常起動できない状態となりました。

2. ソフトウェアのバージョン

  • Windows 10 Home (x64) 1803、ビルド:17134.254
  • VirtualBox:5.2.18 r124319
  • ゲストOS:Ubuntu18.04

3. 症状

3.1 ゲストOSのUbuntuが起動しない

 VirtualBoxからゲストOSのUbuntuを起動しようとしても、応答せず、起動しません。

f:id:toranosuke_blog:20180922112649p:plain:w400
画面が真っ暗でUbuntuが起動しない。

 このとき、CryptSvc (Cryptographic Services)の負荷が上昇します。

 f:id:toranosuke_blog:20180922113240p:plain:w500
私のdynabookの場合、通常は0%のCPU使用率が数%程度となる。

3.2 CryptSvcを停止しても起動しない

 CyptSvcの暴走が原因のようなので、CryptSvcを停止しましたが、今度は異なるエラーで起動しません。

f:id:toranosuke_blog:20180922113728p:plain:w500
今度は、ubuntuの起動以前の段階で停止しているようです。

3.3 原因の推測

 CryptSvcが起動していれば、ubuntuを起動するフェーズに入れるが、ubuntuを起動するフェーズに入ると、CryptSvcが暴走し起動を阻害するので、一旦、CryptSvcが停止させる必要がある、といったところではないかと思います。

① ubuntuの起動フェーズに入る(CyptSvcが必要)→ CryptSvcが暴走する
② ubuntuの起動中に待ち状態になる(画面が黒)← CryptSvcが起動を阻害する
③ CryptSvcを停止する → 待ち状態が解消し、起動が進行する

4. とりあえずの解決策

 この問題は、以下の方法で回避できます。

  • ubuntuの起動中にCryptSvcを再起動する

 CryptSvcの停止のタイミングにシビアな印象はありませんが、タスクマネージャからの停止だと面倒なので、スクリプトを書いておくと楽です。

net stop CryptSvc
net start CryptSvc

 上記のバッチファイルを管理者特権で実行すれば、CryptSvcが再起動します(ちょっとだけ楽にするために改良したスクリプトは、ここ)。

 なお、根本的な解決方法の一つはクリアインストールです。私の場合、諸事情でWin10をクリアインストールする羽目になって、この問題は根本的に解決しました(笑)。

5. 最後に

 Microsoftさん、CyptSvcの暴走問題を早く解決してくださいませ。

(2018/9/22)

関連記事

Windows10のインストールメモ

【概要】Windows10の筆者用のカスタマイズのための設定についてまとめました。リカバリメディア・バックアップの作成、WindowsOSの設定、アプリのインストール,、機器設定などについて述べます。

1. はじめに

 最近、何回かWindowsを再インストールする羽目になったので、メモしておきます。

  • 対象マシン:dynabook AZ77

 我が家のメインマシンdynabook az77についての記事ですが、サブマシンのVOYO V3も同じような設定です。

VOYO V3は中華製4K対応ミニパソコンですが、SSD128GB搭載で、ハードディスク時代のdynabookよりも快適でした(笑)。関連記事は、ここ

2. Windowsの設定

2.1 Windows Updateとバックアップ

2.1.1 リカバリメディアの作成

 クリアインストールするときに必須なメディアを作成する。復旧にも利用できる。

  • 「アプリ」→「TOSHIBA」→「リカバリメディア作成ツール」
    • DVD3枚にバックアップ
    • USBフラッシュの場合、16GB以上必要

2.1.2 回復ドライブの作成

  • 「アプリ」→「Windows管理ツール」→「回復ドライブ」→「システムファイルを回復ドライブにバックアップします」にチェック
    • メディアに必要な容量は、16GBも必要だったかな?VOYOの場合は、8GBも要らなかった。
※ 回復ドライブを作れば、 システム修復ディスクの作成は不要*1
● 「設定」→「更新とセキュリティ」→「バックアップ」→「[バックアップと復元]に移動(Windows 7)」→「システムイメージの作成」(DVDで1枚)

2.1.3 Windows Update

  • 「設定」→「更新とセキュリティ」→「Windows Update」
    • 数時間を要する。
    • バージョン:1803, ビルド:17134.254へバージョンアップ

2.1.4 東芝からのソフトアップデート

  • 「アプリ」→「TOSHIBA」→「Service Station」
    • TOSHIBA Service Station(東芝サービスステーション)でアップデート

2.1.5 バックアップの作成

  • 「設定」→「更新とセキュリティ」→「バックアップ」→「[バックアップと復元]に移動(Windows 7)」→「システムイメージの作成」
    • 160GBの外付けハードディスクを接続して、バックアップ(約70GB)

2.1.6 復元ポイントの作成

  • 「アプリ」→「Windows システムツール」→「コントロールパネル」→「システムとセキュリティ」→「システム」→「システムの詳細設定」→「システムの保護」タブ→「復元ポイントを今すぐ作成します」→「作成(C)」

2.2 マシン名の変更

  • 「設定」→「システム」→「バージョン情報」→「このPCの名前を変更」
    • 「DESKTOP-47V1BAU」→「kaliwin」→再起動

2.3 設定の同期

 背景などの「個人用設定画面」やMicrosoft Edgeの「お気に入り」などが、Microsoftアカウントの設定と同期する。

  • 「設定」→「アカウント」→「設定の同期」

 「確認」が必要な場合には、Microsoftアカウントのメールアドレスへのセキュリティコードの送信を行う。

2.4 ウィンドウのスナップをオフ

 ウィンドウを画面の端にドラッグしたときに最大化するなど、スナップ機能をオフにする。

  • 「設定」→「システム」→「マルチタスク」→「スナップ」をオフにする。

2.5 電源とスリープ

  • 「設定」→「システム」→「電源とスリープ」
    • 「画面」→「電源接続時」→「3時間」
    • 「スリープ」→「電源接続時」→「なし」
  • 「設定」→「システム」→「電源とスリープ」→「電源の追加設定」
    • 「電源ボタンを押したときの動作」:「スリープ状態」のまま
    • 「カバーを閉じたときの動作」:「スリープ状態」から「何もしない」に変更

2.6 ディスプレイ

  • 「設定」→「システム」→「ディスプレイ」
    • 「複数のディスプレイ」→「2のみに表示する」
      • ディスプレイ2
        • 「サイズを変更する」→「100%」
        • 「解像度」→「3840x2160(推奨)」

2.7 スクリーンセーバー

  • 「設定」→「個人用設定」→「ロック画面」→「スクリーンセーバー設定」

2.8 Wi-Fi

2.8.1 内蔵wifiの無効化

 BuffaloのWifiドングルのみに限定する(内蔵のwifiは不安定なため)。

  • 「設定」→「ネットワークとインターネット」→「Wi-Fi」→「アダプタのオプションを変更する」
    • 「Wi-Fi」を「無効にする」
    • 「Wi-Fi2」の「名前の変更(M)」→「buffalo-wifi」(5GHzに接続すること)
  • 「アプリ」→「TOSHIBA」→「システムセッティング」→「LAN」
    • 「内蔵LAN」:(必要に応じて)無効
    • 「東芝システムセッティング」で起動装置の優先順位などでも設定可能

2.8.2 固定IPアドレス設定

 必要に応じて、IPアドレスを固定する。

  • 「設定」→「ネットワークとインターネット」→「Wi-Fi」→「アダプタのオプションを変更する」(右列にある)
    • 「buffalo-wifi」を右クリック→「プロパティ」→「インターネットプロコル バージョン4(TCP/IPv4)」→「プロパティ」
      • 「次のIPアドレスを使う(S)」にチェック
        • 「IPアドレス(I)」:192.168.1.181
        • 「 サブネットマスク(U)」:255.255.255.0
        • 「デフォルトゲートウェイ(D)」:192.168.1.1
      • 「次のDNSサーバのアドレスを使う(E)」にチェック
        • 「優先DNSサーバ(P)」:192.168.1.1

2.9 Microsoft IMEの設定

  • 「タスクバー」→「Microsoft IME」→「プロパティ」→「Microsoft IMEの設定」
    • 「IME入力モード切替の通知」→「画面中央に表示する」のチェックを外す。
  • あるいは、「設定」→「時刻と言語」→「地域と言語」→「日本語(Windowsの表示言語)」→「オプション」→「Microsoft IME(入力方式エディター)」→「オプション」→「IME 入力モードの通知」→「画面中央に入力モードを表示する」を「オフ」にする。

2.10 CapsLockをCtrlに入れ替える

2.11 完全シャットダウンのショートカット作成

 完全シャットダウンのショートカットを作成する。

  • 「デスクトップ」で右クリック→「新規作成(X)」→「ショートカット(S)」
    • 完全シャットダウン
      • コマンド「shutdown /s /t 0」
      • 名前「full_shutdown」
    • 再起動
      • コマンド「shutdown /r /t 0」
      • 名前「full_reboot」
  • 「シフトキー」+「シャットダウン」でも完全シャットダウンは可能。

2.12 ユーザーフォルダ名の変更

 Windowsが生成したユーザーフォルダ名を「tora」に変更する。

  • ① 現在のMicrosoftアカウントをローカルアカウントに切り替える。
    • 「ローカルアカウントでのサインインに切り替える」
      • このときのユーザー名は、tempなどで、toraにはしない。
      • パスワードは空白で構わない。
  • ② 新規ローカルアカウントを作成する。
    • 「その他のユーザーをこのPCに追加」→「このユーザーのサインイン情報がありません」→「Microsoftアカウントを持たないユーザーを追加する」
      • 「ユーザー名」に「tora」を入力(ユーザーフォルダは、C:\Users\toraとなる)
      • パスワードは空白で構わない。
      • 「アカウントの種類の変更」で「管理者」にする。
    • サインアウトし、toraでログオンする。
  • ③ toraをMicrosoftアカウントでのサインインに切り替える。
    • 「Microsoftアカウントでのサインインに切り替える」
    • Microsoftアカウントでサインインする。
    • 現在のWindowsパスワード(ローカルアカウントtoraのパスワード、つまり空白)を入力
    • 初めてサインインするときの設定画面が現れ、いくつか設定する。
  • ④ C:\Users\以下のディレクトリを確認し、必要なものはコピーする。
  • ⑤ 古いアカウントを削除する。
    • ローカルアカウント「temp」を削除する。
  • ⑥ 古いフォルダを削除する。
    • 不要なC:\Users\xxxを削除する
      • 一回、名前変更して、再起動後に、削除した方が安心

 詳細は、以下を参照。

3. アプリケーション

3.1 アプリの削除

  • 「設定」→「アプリ」
    • 「ウィルスバスタークラウド」のアンインストール→再起動
    • 「WinZip 19.5」のアンインストール

3.2 ブラウザ

3.3 Acrobat Reader DC

3.4 Googleドライブ(バックアップと同期)

  • https://www.google.com/drive/からダウンロード
  • フォルダの場所:「C:\Users\tora\GoogleDrive」に変更
    • スペース・日本語があると、VirtualBoxでの共有フォルダ設定に不便

3.5 VLC media player

3.6 カスペルスキーインターネットセキュリティ

3.6.1 インストール

3.6.2 スキャン

  • メイン画面で「推奨項目:1件」→「詳細」→Internet Explorerにプラグインをインストール
  • 「便利ツール」→「脆弱性スキャン」
    • ハードディスク、ネットワークドライブ、リムーバブルドライブの自動実行を無効にする

3.6.3 定期的なスキャンの設定

「スキャン」→「スキャンスケジュール」でスキャンのスケジュールを設定する。

  • 完全スキャン
    • 「毎月」「1日」「午前9時」「翌日実行」で設定
  • 簡易スキャンスケジュール
    • 「毎月」「15日」「午前9時」「翌日実行」で設定
  • 脆弱性スキャン
    • 「毎月」「7日」「午前9時」「翌日実行」で設定
  • Windows Defenderのスキャンを併用
    • 「設定」→「更新とセキュリティ」→「Windowsセキュリティ」→「Windows Defenderセキュリティセンター」→「ウイルスと脅威の防止」→「Windows Defenderウイルス対策のオプション」→「定期的なスキャン」を「ON」

3.7 VirtualBox

3.7.1 VirtualBoxのインストール

  • https://www.virtualbox.org/からダウンロード
    • VirtualBox 5.2.18 platform packages (5.2.18 r124319)
    • VirtualBox 5.2.18 Oracle VM VirtualBox Extension Pack
  • VirtualBoxのインストール後、拡張パックをインストールする。
    • 「ファイル(F)」→「環境設定」→「拡張機能」→「+」
    • 「Oracle_VM_VirtualBox_Extension_Pack-5.2.18.vbox-extpack」を選択し、インストール
      • エラーコードVERR_ACCESS_DENIEDでインストールに失敗。
      • VirtualBoxの起動し直し、3度目で成功した(謎)

3.7.2 仮想マシン(ubuntu)を復旧する

  • バックアップした「VirtualBox VMs」を元の場所(C:\Users\tora)に戻す。
    • 「仮想マシン(M)」→「追加(A)」→「VirtualBox VMs\ubuntu16.04\ubuntu1604.vbox」を開く。
  • 「設定(S)」を確認する。

3.7.3 ゲストOS(ubuntu)の設定

  • Guest Additionのインストール
    • 仮想マシンのストレージ(光学ドライブ)にVBoxGuestAdditions.isoを設定
      • パスは、「C:\Program Files\Oracle\VirtualBox\VBoxGuestAdditions.iso」
  • Ubuntu側からファイルマネージャ(Caja)で、「VBox_GAs_5.2.18」にアクセスしようとしても、「VBox_GAs_5.2.18をマウントできません」とエラーとなる場合がある。この場合、コマンドラインでマウントする。
    • sudo mount -r /dev/sr0 /mnt/tmp
    • 「cd /mnt/tmp/」「 ./autorun.sh」を実行する(VBoxLinuxAdditions.runでも可)
  • Ubuntuのアップデート:「apt-get update」「apt-get upgrade」を実施

3.7.4 仮想ディスクのサイズの縮小

 500GBへのSSDに入れたために、SSDの空き容量が80GBと余裕がなくなった。ゲストOS上の不要ファイルを削除して、仮想ディスクのサイズを縮小する。

  • ① ゲストOS(ubuntu)の不要ファイルを削除する。
    • 170GB程度を削除して、使用量は90GB程度。この他にswap領域として4GBが確保されている。
$ df
Filesystem                 1K-blocks       Used Available Use% Mounted on
udev                         2012376          0   2012376   0% /dev
tmpfs                         404612       6500    398112   2% /run
/dev/mapper/kali--vg-root  475595856   85649708 365764192  19% /
tmpfs                        2023044        152   2022892   1% /dev/shm
tmpfs                           5120          0      5120   0% /run/lock
tmpfs                        2023044          0   2023044   0% /sys/fs/cgroup
/dev/sda1                     240972     197906     30625  87% /boot
cgmfs                            100          0       100   0% /run/cgmanager/fs
tmpfs                         404612         36    404576   1% /run/user/1000
  • ② 仮想ディスク上の空き領域を0で埋める。
$ dd if=/dev/zero of=zero.file bs=1M ; /bin/rm zero.file
  • ③ VBoxManageで仮想ディスクを縮小する。
> C:\Program Files\Oracle\VirtualBox\VBoxManage.exe list hdds
UUID:           ca2a90cc-7db8-451e-8dab-f1c875bbaecc
Parent UUID:    base
State:          created
Type:           normal (base)
Location:       C:\Users\tora\VirtualBox VMs\ubuntu16.04\ubuntu1604.vdi
Storage format: VDI
Capacity:       512000 MBytes
Encryption:     disabled

調べたuuidでディスクを指定して、縮小する。

> C:\Program Files\Oracle\VirtualBox\VBoxManage.exe modifyhd ca2a90cc-7db8-451e-8dab-f1c875bbaecc --compact

 仮想ディスク(ubuntu1604.vdi)は、290,056,044,544 バイトから 109,592,969,216 バイトへと、約180GBの縮小。

参考:ソフトウェア/VirtualBox/ディスクサイズの拡大・縮小 - 武内@筑波大

3.7.5 共有フォルダの設定

 共有フォルダの設定を確認する。

 ユーザーフォルダ名を変更すると、パスが変更される。また、ubuntuやVirtualBoxのバージョンアップの影響で動作が変わることもしばしばある。

3.7.5.1「共有フォルダー」のパスを確認する

  • 「設定(S)」→「共有フォルダー」タブ→右端のアイコン(追加、編集、削除)のポップアップウィンドウで、設定する(「 永続化する(M)」にもチェック)。
    名前 パス 自動マウントアクセス権マウント先
    gdrive C:\Users\GoogleDriveはい 完全 /media/sf_gdrive
    win10 C:\Users\tora\home はい 完全 /media/sf_win10
    music C:\Users\tora\Music はい 読込専用/media/sf_music

3.7.5.2 自動マウントされない場合

 VirtualBox側で自動マウントを指定しても、自動マウントされない場合がある。

  • 対策1:/etc/fstab に以下を追加
gdrive  /media/sf_gdrive        vboxsf defaults 0 0
win10   /media/sf_win10         vboxsf defaults 0 0
music   /media/sf_music         vboxsf ro       0 0
  • groupをvboxsfにしたい場合には、gid=vboxsfを追加する。
  • VirtualBox側では自動マウントしない設定にしておく方が、無難
    (たぶん、fstabが優先)。

参考:Virtualboxの共有フォルダのマウント位置やパーミッションを調整する - わたしの開発日記

  • 対策2:マウントをスクリプト化し、必要なときにマウント。
    #!/bin/sh
    sudo mount.vboxsf gdrive /media/sf_gdrive
    sudo mount.vboxsf win10  /media/sf_win10
    sudo mount.vboxsf -r music  /media/sf_music
    

注:vboxsfには、umountコマンドがないが、guest additionのサービスを再起動すると、マウントが外れる。

sudo /opt/VBoxGuestAdditions-5.2.18/init/vboxadd restart

3.7.6 Ubuntuのバージョンアップ

 16.04から18.04へバージョンアップする。

  • ① 仮想マシンのクローン
    • 「仮想マシン(M)」→「クローン(O)」→「新しいマシン名」(「ubuntu18.04」を設定)→「すべてをクローン(F)」
  • ② 新しい仮想マシンを起動して、ubuntuを18.04へアップグレード(sudo do-release-upgrade)
  • ③ 不要なbootイメージを削除する(/bootの空きがなくなりエラー発生)。再実行。
$ dpkg --get-selections | grep linux- | grep deinstall  
linux-image-4.4.0-116-generic           deinstall
linux-image-4.4.0-119-generic           deinstall
linux-image-4.4.0-121-generic           deinstall
linux-image-4.4.0-124-generic           deinstall
 :
(これらのパッケージを削除する)
$ sudo apt-get purge linux-image-4.4.0-{116,119,121,124} 
$ sudo do-release-upgrade

参考:bootディレクトリの容量不足でUbuntuがアップデートできない時の対処 | Hornet|静岡拠点のWeb、ホームページ制作

  • ubuntuの18.04へのバージョンアップによって発生した現象
    • 共有フォルダが自動マウントされない
    • VBoxGuestAdditions.isoがエラーせずマウントできる
    • ウィンドウのスナップ設定がリセット
      • 18.04へのバージョンアップで、ウィンドウのスナップが有効化(MATE デスクトップは、1.12.1から1.20.1にバージョンアップ)。
      • 「システム」→「設定」→「ウィンドウ」→「場所」タブ→「ウィンドウのスナップ」→「Enable window tiling」をオフ

3.8 iTunes

  • 音楽データ
    • バックアップした「iTunes」フォルダを「ミュージック」フォルダにコピーする。
  • iTunesをインストールする。
  • iTunesの設定
    • 「アカウント(A)」→「サインイン(S)」
    • 「アカウント(A)」→「認証(A)」→「このコンピュータを認証(A)...」
      • 既に5台のパソコンが認証されていたので、1台のみに変更する。
        • 「アカウント(A)」→「マイアカウントを表示(V)...」→「すべて認証解除」
        • 改めて、「このコンピュータを認証(A)」を実行する
    • ダウンロードの設定
      • 「編集(E)」→「環境設定(F)」→「ダウンロード」タブ
      • 「ミュージック(M)」「映画(O)」にチェック
      • 「フルサイズHDビデオをダウンロード(V)」にチェック
  • iPhone のバックアップ
    • iPhone を接続
    • 「ファイル(F)」→「デバイス(V)」→「バックアップ」

3.9 Amazon Music

  • 音楽データ
    • バックアップした「Amazon Music」フォルダを「ミュージック」フォルダにコピー。
  • https://music.amazon.co.jp/→「ストア」→「Amazon Musicアプリ」からダウンロード

3.10 その他

4. 機器の設定

4.1 HPプリンタ Officejet 6500

  • Officejet 6500 E709c用のドライバ・ソフトウェア(HPソリューションセンター)のインストール(HP製)
  • Officejet 6500 E709のドライバのインストール(Windows標準ドライバ, 非推奨)
    • 「設定」→「デバイス」→「プリンターとスキャナー」→「プリンターとスキャナの追加」→「プリンタが一覧にない場合」→「少し古いプリンタを検索する(R)」
      • 検索して見つかった「Officejet 6500 E709n (HP)」を選択し、プリンタ名、プリンタ共有などを設定する。
      • 注:プリントしたときに、下の余白が大きすぎる。また、はがき印刷、写真印刷(フチなし)などの設定ができない。
  • 注:Officejet側の電源を入れて、スリープ状態から印刷可能な状態にしておくこと

4.2 Canonスキャナ imageFORMULA DR-C240

  • ドライバ
  • CapturePerfect
    • DVDからインストール
      • 「選んでインストール」
        • 「CapturePerfect」「ユーザーマニュアル(機能詳細編)」を選択
        • 「DR-C240ドライバー」「CaptureOnTouch」「eCopy PDF」は不要
    • CapturePerfect のバージョンアップデータ (オリジナルのDVDが必要)
  • 再起動

4.3 ZOXテレビチューナー DS-DT308

  • Chusei PVR
    • chusei_pvr8_32_01.exeを展開
    • setup.exeを実行
      • 「CHUSEI PVR」「Driver for 1 SEG Tuner」をインストール
      • シリアル番号を入力
      • 再起動
    • チャンネルスキャン
      • 都道府県を選択し、「地域スキャン」

5. 最後に

 内容は、随時、アップデートしていきます。

(2018/9/21)

関連記事