ubicast Bloggerの設定が保存できない件
以前、1.1.25のときに
My DocumentsやApplication Dataをサーバーにリダイレクトしていると、保存に失敗するよん。
と報告したのだが、
反応無いし、1.1.40でも直ってないので、ちょい詳しく報告してみる。
調べてみると、CreateDirectoryというWin32 APIがエラーを返していることが、直接の原因らしい。
引数に渡しているのはヌル文字列L""なので、当然か。
呼び出し部分のコードはこんな感じ。
bloggeru.exeモジュールは0x00420000にロードされている。
0042BC20
mov
eax,2804h
0042BC25 call
004FB960
0042BC2A
mov eax,dword ptr
ds:[00604C74h]
0042BC2F push
ebx
0042BC30
mov ebx,dword ptr
[esp+280Ch]
0042BC37 push
ebp
0042BC38 push
esi
0042BC39 push
edi
0042BC3A push
ebx
0042BC3B
mov dword ptr
[esp+2814h],eax
0042BC42 call
dword ptr ds:[5114F0h]
0042BC48 test
eax,eax
0042BC4A
je
0042BC75
0042BC4C
lea
eax,[esp+810h]
0042BC53 push
eax
0042BC54 push
0FFFh
0042BC59 call
dword ptr ds:[51017Ch]
0042BC5F push
ebx
0042BC60
lea
ecx,[esp+814h]
0042BC67 push
ecx
0042BC68 call
dword ptr ds:[51150Ch]
0042BC6E
lea
ebx,[esp+810h]
0042BC75
mov ebp,dword ptr
ds:[5101F8h]
0042BC7B
mov edi,ebx
0042BC7D
lea
ecx,[ecx]
0042BC80
mov ax,word ptr
[edi]
0042BC83
cmp ax,5Ch
0042BC87
je
0042BCA2
0042BC89
lea
esp,[esp]
0042BC90 test
ax,ax
0042BC93
je
0042BCA2
0042BC95
mov ax,word ptr
[edi+2]
0042BC99
add edi,2
0042BC9C
cmp ax,5Ch
0042BCA0
jne
0042BC90
0042BCA2
mov esi,edi
0042BCA4
sub esi,ebx
0042BCA6
sar esi,1
0042BCA8
lea
edx,[esi+1]
0042BCAB push
edx
0042BCAC push
ebx
0042BCAD
lea
eax,[esp+18h]
0042BCB1 push
eax
0042BCB2 call
ebp
0042BCB4
lea
eax,[esp+esi*2+10h]
0042BCB8
mov word ptr
[eax],0
0042BCBD
cmp word ptr
[eax-2],3Ah
0042BCC2
je
0042BCE3
0042BCC4
lea
ecx,[esp+10h]
0042BCC8 push
ecx
0042BCC9 call
dword ptr ds:[511500h]
0042BCCF test
eax,eax
0042BCD1
jne
0042BCE3
0042BCD3 push
eax
0042BCD4
lea
edx,[esp+14h]
0042BCD8 push
edx
0042BCD9 call
dword ptr ds:[510180h]
0042BCDF test
eax,eax
0042BCE1
je
0042BCEE
0042BCE3
cmp word ptr
[edi],0
0042BCE7
je
0042BD07
0042BCE9
add edi,2
0042BCEC
jmp
0042BC80
0042BCEE
pop
edi
0042BCEF
pop
esi
0042BCF0
pop
ebp
0042BCF1
xor eax,eax
0042BCF3
pop
ebx
0042BCF4
mov ecx,dword ptr
[esp+2800h]
0042BCFB call
004FB88D
0042BD00
add
esp,2804h
0042BD06
ret
0042BD07
mov ecx,dword ptr
[esp+2810h]
0042BD0E
pop
edi
0042BD0F
pop
esi
0042BD10
pop
ebp
0042BD11
mov eax,1
0042BD16
pop
ebx
0042BD17 call
004FB88D
0042BD1C
add
esp,2804h
0042BD22
ret
このままだと見づらいので、Cっぽく手動変換。
0042BC20
mov
eax,2804h
0042BC25 call
004FB960
0042BC2A
mov eax,dword ptr
ds:[00604C74h]
0042BC2F push
ebx
0042BC30
mov ebx,dword ptr
[esp+280Ch]
0042BC37 push
ebp
0042BC38 push
esi
0042BC39 push
edi
if (PathIsRelative(wzPath))
0042BC3A push
ebx
0042BC3B
mov dword ptr
[esp+2814h],eax
0042BC42 call
dword ptr ds:[5114F0h]
0042BC48 test
eax,eax
0042BC4A
je
0042BC75
{
GetCurrentDirectoryW(wzTemp);
0042BC4C
lea
eax,[esp+810h]
0042BC53 push
eax
0042BC54 push
0FFFh
0042BC59 call
dword ptr ds:[51017Ch]
PathAppendW(wzTemp, wzPath);
0042BC5F push
ebx
0042BC60
lea
ecx,[esp+814h]
0042BC67 push
ecx
0042BC68 call
dword ptr ds:[51150Ch]
wzPath = wzTemp;
0042BC6E
lea
ebx,[esp+810h]
LPWSTR *wcsPtr = wzPath;
0042BC75
mov ebp,dword ptr
ds:[5101F8h]
0042BC7B
mov edi,ebx
0042BC7D
lea
ecx,[ecx]
while (true)
{
if (*wcsPtr !=
L'\\')
0042BC80
mov ax,word ptr
[edi]
0042BC83
cmp ax,5Ch
0042BC87
je
0042BCA2
0042BC89
lea
esp,[esp]
{
while (*wcsPtr != L'\0')
0042BC90 test
ax,ax
0042BC93
je
0042BCA2
{
if (*++wcsPtr == L'\\')
{
break;
}
}
0042BC95
mov ax,word ptr
[edi+2]
0042BC99
add edi,2
0042BC9C
cmp ax,5Ch
0042BCA0
jne
0042BC90
}
int cchFolder = wcsPtr
- wzPath;
042BCA2 mov
esi,edi
0042BCA4
sub esi,ebx
0042BCA6
sar
esi,1
lstrcpynW(wzBuf,
wzPath, cchFolder + 1);
0042BCA8
lea
edx,[esi+1]
0042BCAB push
edx
0042BCAC push
ebx
0042BCAD
lea
eax,[esp+18h]
0042BCB1 push
eax
0042BCB2 call
ebp
wzBuf[cchFolder]
= L'\0';
0042BCB4
lea
eax,[esp+esi*2+10h]
0042BCB8
mov word ptr
[eax],0
if (wzBuf[cchFolder -
1] != L':')
0042BCBD
cmp word ptr
[eax-2],3Ah
0042BCC2
je
0042BCE3
{
if
(!PathFileExistsW(wzBuf))
0042BCC4
lea
ecx,[esp+10h]
0042BCC8 push
ecx
0042BCC9 call
dword ptr ds:[511500h]
0042BCCF test
eax,eax
0042BCD1
jne
0042BCE3
{
if (!CreateDirectoryW(wzBuf, 0))
goto LError;
}
0042BCD3 push
eax
0042BCD4
lea
edx,[esp+14h]
0042BCD8 push
edx
0042BCD9 call
dword ptr ds:[510180h]
0042BCDF test
eax,eax
0042BCE1
je
0042BCEE
}
if (*wcsPtr ==
L'\0')
goto
LExit;
0042BCE3
cmp word ptr
[edi],0
0042BCE7
je
0042BD07
wcsPtr++;
}
0042BCE9
add edi,2
0042BCEC
jmp
0042BC80
:LError
0042BCEE
pop
edi
0042BCEF
pop
esi
0042BCF0
pop
ebp
0042BCF1
xor eax,eax
0042BCF3
pop
ebx
0042BCF4
mov ecx,dword ptr
[esp+2800h]
0042BCFB call
004FB88D
0042BD00
add
esp,2804h
0042BD06
ret
:LExit
0042BD07
mov ecx,dword ptr
[esp+2810h]
0042BD0E
pop
edi
0042BD0F
pop
esi
0042BD10
pop
ebp
0042BD11
mov eax,1
0042BD16
pop
ebx
0042BD17 call
004FB88D
0042BD1C
add
esp,2804h
0042BD22
ret
たぶんソースはこんな感じ。
hoge(LPWSTR wzPath)
{
WCHAR wzTemp[MAX_PATH];
if (PathIsRelative(wzPath))
{
GetCurrentDirectoryW(wzTemp);
PathAppendW(wzTemp,
wzPath);
wzPath =
wzTemp;
}
LPWSTR wcsPtr = wzPath;
while (true)
{
WCHAR
wzBuf[MAX_PATH];
if (*wcsPtr !=
L'\\')
{
while
(*wcsPtr != L'\0')
{
if (*++wcsPtr == L'\\')
{
break;
}
}
}
int cchFolder = wcsPtr
- wzPath;
lstrcpynW(wzBuf,
wzPath, cchFolder + 1);
wzBuf[cchFolder] =
L'\0';
if (wzBuf[cchFolder -
1] != L':')
{
if
(!PathFileExistsW(wzBuf))
{
if
(!CreateDirectoryW(wzBuf, 0))
goto
LError;
}
}
if (*wcsPtr ==
L'\0')
goto
LExit;
wcsPtr++;
}
LError:
//略
LExit:
//略
}
たとえばMy Documentsが、
サーバー名:MyServer
共有名:Users
フォルダー:me\マイ ドキュメント
にリダイレクトされていると、
wzPathにはL"\\\\MyServer\\Users\\me\\マイ
ドキュメント\\マイエントリー"とかいう文字列が渡されてくる。
するとこの関数は、
L""
L"\\"
L"\\\\MyServer"
L"\\\\MyServerr\\Users"
L"\\\\MyServerr\\Users\\me"
L"\\\\MyServerr\\Users\\me\\マイドキュメント"
L"\\\\MyServerr\\Users\\me\\マイドキュメント\\マイ
エントリー"
というフォルダーを順に調べて、無ければ作ろうとするのだが、
最初のL""でCreateDirectoryWがエラーを返すという訳だ。
最後のやつ以外をdebuggerでスキップしてやれば、無事に保存できた。
フォルダーのリダイレクトは、自宅に限らず企業(私の勤務先を含め)では普通に使われている機能ではなかろうか?
全社員のデータをサーバーに集めておけば、まとめてバックアップが取れるのです。