![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ERROR_MR_MID_NOT_FOUND и как с ней бороться ?
Riply © (2007-04-27 02:06:00)Здравствуйте !
В последнее время, GetLastError повадился часто выдавать САБЖ - ую ошибку:
"The system cannot find message text for message number 0x%1 in the message file for %2."
(Наверное, ему просто лень искать :)
Причем после простейших операций типа: GetOverlappedResult, ReadFileEx и т.п.
Подскажите, пожалуйста, с чем это может быть связано и как бороться ?
Riply (2007-04-27 17:31:00) [1]Еще раз всем спасибо.
P.S. Вот какие интересные для себя вещи узнаешь на форуме в процессе обсуждения.
Я ведь тоже считала, что
"Если MS рекомендует вызывать GetLastError при любом значении,возвращаемом функцией ReadFileEx,
значит эта функция всегда устанавливает LastError"
Игорь Шевченко (2007-04-27 17:26:00) [2]
> Показывает "666"
Значит использовать совет [32]
Riply (2007-04-27 17:23:00) [3]Проверила:
SetLastError(666);
if ReadFileEx(FhPipe, pData, cbData, @FOverLapRead, pCallBack)
then
begin
ReadErr := GetLastError;
ShowMessage(IntToStr(ReadErr));
Показывает "666"
Riply (2007-04-27 17:13:00) [4]>[35] Игорь Шевченко © (27.04.07 16:47)
>Проверить впрочем дело 2-х минут:
Пойду проверять еще раз.
Riply (2007-04-27 17:11:00) [5]>[33] Сергей М. © (27.04.07 16:35)
>Ах ты ж горемычная наша !)
"горемычной" я была, пока не понимала в чем дело.
Теперь "не горемычная" до следующей ошибки :)
> [34] Игорь Шевченко © (27.04.07 16:43)
>Без обид, ничего личного :)
Какие могут быть обиды - абсолютно верное утверждение :)
>[32] clickmaker © (27.04.07 16:32)
>можно перед ReadFileEx сказать SetLastError(ERROR_SUCCESS)
Как все просто, а я уж собралась анализировать LastError и перед ReadFileEx :)
Сергей М. (2007-04-27 16:48:00) [6]Ну вот и Игорь не выдержал)
Игорь Шевченко (2007-04-27 16:47:00) [7]
> Значит, анализируя GetLastError после ReadFileEx, надо учитывать,
>
> что эта функция может и не менять LastError, если возвращает
> True :)
Если MS рекомендует вызывать GetLastError при любом значении,возвращаемом функцией ReadFileEx, значит эта функция всегда устанавливает LastError
Проверить впрочем дело 2-х минут:
SetLastError(66666666);
ReadFileEx (.....)
ShowMessageFmt('%d', [GetLastError]);
Игорь Шевченко (2007-04-27 16:43:00) [8]Riply © (27.04.07 16:05) [31]
Never attribute to malice which can be adequately explained by stupidity.
Без обид, ничего личного :)
Сергей М. (2007-04-27 16:35:00) [9]
> Riply © (27.04.07 16:05) [31]
Ах ты ж горемычная наша !)
Ты ж, разумеется, не в состоянии запросить N раз по не более чем K байт, вместо требования "дай мне сразу всеN * M байт"
clickmaker (2007-04-27 16:32:00) [10]
> анализируя GetLastError после ReadFileEx, надо учитывать,
>
> что эта функция может и не менять LastError, если возвращает
> True
можно перед ReadFileEx сказать SetLastError(ERROR_SUCCESS)
Riply (2007-04-27 16:05:00) [11]>[28] Сергей М. © (27.04.07 14:32)
>Тогда и не пытайся читать/писать зараз более 4-х кбайт - вот и проблем не будет)
Да-а-а, а вруг кто-то нерадивый(или злоумышленник) отправит более 4-х кбайт ?
Мне тогда вылетать с каким-нибудь AV ? :)
>[26] Игорь Шевченко © (27.04.07 14:19)
>2. Что говорит отладчик, если узнать значение переменной ReadErr перед вызовом этой процедуры ?
Вы, впочем как и всегда, оказались правы. :)
Поднялась вверх по коду в поисках места, где впервые возникает ERROR_MR_MID_NOT_FOUND.
Добралась аж до самого начала:
while not Terminated do
begin
Result := CreateFile(PChar(FPipeName),
GENERIC_WRITE or GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE,
pSecurAttr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if Result <> INVALID_HANDLE_VALUE then Exit;//<---!!!
Result := 0;
FLastErr := GetLastError;
if FLastErr <> ERROR_PIPE_BUSY
then Exit
else
if WaitNamedPipe(PChar(FPipeName), FDefaultTimeOut) then Continue;
FLastErr := GetLastError;
end;
На строчке, помеченной "!!!" я выхожу не инициализируя FLastErr.
Потом (спустя некоторое время) пытаюсь получить SysErrorMessage(FLastErr)
и забиваю значение GetLastError-а сабжевой ошибкой,
которая успешно сохраняется до вызова ReadFileEx :)
Всем огромное спасибо !
P.S. Значит, анализируя GetLastError после ReadFileEx, надо учитывать,
что эта функция может и не менять LastError, если возвращает True :)
Что не есть, imho, правильно. А вдруг LastError до нее имеет значение ERROR_MORE_DATA ?
Игорь Шевченко (2007-04-27 15:53:00) [12]
> Сейчас посмотрю, но не понимаю какое это имеет значение.
> Ведь ReadErr мы получаем так:
Между тем, что показывает отладчик, и тем, что происходит в твоей (не выложенной) процедуре может быть какая-то разница. В конце концов можно сразу после получения ReadErr вывести ее значение (хоть через ShowMessage)
Riply (2007-04-27 14:41:00) [13]> [26] Игорь Шевченко © (27.04.07 14:19)
>1. Код в студию.
В коде у меня много вложенных собственно-лапно написанных функций(кирпичиков). :)
Попробую привести его в нормальный вид.
>2. Что говорит отладчик, если узнать значение переменной ReadErr перед вызовом этой процедуры ?
Сейчас посмотрю, но не понимаю какое это имеет значение. Ведь ReadErr мы получаем так:
if ReadFileEx(FhPipe, pData, cbData, @FOverLapRead, pCallBack)
then
begin
ReadErr := GetLastError;
Post_PipeError(ReadErr, 'TChannel._ReadPipeEx--->ReadFileEx--->True');
Если только ReadFileEx не всегда использует SetLastError
Сергей М. (2007-04-27 14:32:00) [14]
> Буферы у меня - 4KB
Тогда и не пытайся читать/писать зараз более 4-х кбайт - вот и проблем не будет)
Riply (2007-04-27 14:30:00) [15]> [24] Сергей М. © (27.04.07 14:06)
>Имеет смысл не устанавливать буферы непотребного размера)
Буферы у меня - 4KB. Для получения ERROR_MORE_DATA пытаюсь отправить (MAXWORD + 1) shl 1 байт.
Считываю первые 4KB и смотрю на возвращаемую ошибку(надеясь на ERROR_MORE_DATA),
но получаю ERROR_MR_MID_NOT_FOUND :(
В Help'е у меня написано:
Requirements
Client: Included in Windows XP, Windows 2000 Professional, Windows NT Workstation,
Windows Me, Windows 98, and Windows 95.
Server: Included in Windows Server 2003, Windows 2000 Server, and Windows NT Server.
Стоит Windows XP SP2. Ошибку ловлю на стороне клиента. Я "соблюла" условия, или я их неправильно понимаю ?
Игорь Шевченко (2007-04-27 14:19:00) [16]
> Post_PipeError(ReadErr, 'TChannel._ReadPipeEx--->ReadFileEx-
> -->True');
> Отправляет ошибку "на эран" и записывает в лог.
1. Код в студию.
2. Что говорит отладчик, если узнать значение переменной ReadErr перед вызовом этой процедуры ?
Сергей М. (2007-04-27 14:07:00) [17]
> из Help'а к BDS 2006
За BDS2006, извини, ничего не скажу.
Тольео вплоть до Д7.
Сергей М. (2007-04-27 14:06:00) [18]Имеет смысл не устанавливать буферы непотребного размера)
Ориентируйся на буферы (и на кл. и на серв. стороне) размерами кратными 4k (дифолтный размер страницы), но размера, соответствующего гранулярности сегмента (по дифолту - 64к)
Riply (2007-04-27 14:03:00) [19]> [21] Сергей М. © (27.04.07 13:59)
> именно в Help'е (по кр.мере - Д7) нет такого комментария
Я это вычитала из Help'а к BDS 2006.
>Ты их "соблюла" ?
>Вряд ли)..
Пошла изучать Help :)
Riply (2007-04-27 14:00:00) [20]Может имеет смысл перехватить GetLastError и попробовать узнать когда эта ошибка появляется впервые ?
Или это бред "сивой кобылы" ?